How can I transfer a file with the .exe extension, say, 30mb in size over a socket? What features to use? What is the algorithm?

// ------------------------------------------------ --------

Faced such a problem: I can not send a file in pieces, that is, I have a buffer of 1024, and a file, say, 17 * 1024. It is impossible to read in turn 1024 bytes from the file . ReadFile & fread reads the entire file, not paying attention to the size of the written buffer. Tried to play with the position in the stream and fgets? but nothing happened either. Who knows how to send the file in parts?

// ------------------------------------------------ ---------

Already figured out, thank you all for your help) The final file transfer code:

FILE *in = fopen("SocketServer.exe","rb"); while(!feof(in)) { b=fread(bufer,1,sizeof(bufer),in); size=ftell(in); printf("bytes read: %d, part:%d, pos: %ld \n",b,i,size); if(b!=0) send(current,bufer,b,0); i++; } 

Well, the reception of the file:

 while (1) { int nbytes = recv( soc, buf, sizeof(buf), 0 ); if ( nbytes == 0) { cout<<"Disconnected."<<endl; return; } if (nbytes < 0) { cout<<"Error: "<<WSAGetLastError()<<endl; return ; } WriteFile(F2,buf,nbytes,&j,NULL); cout<<nbytes<<","<<i<<endl; i++; } 
  • You work with a socket as with an ordinary file. The easiest way is to simply open the exe file for reading and write it to the socket. Well, somehow loom like "data start", "data", "end of data" - AlexDenisov
  • Nowhere did I find a normal example of file transfer over sockets. Please show a piece of code where the opening of the file and its transfer through the socket is realized. - Yaroslav Schubert
  • one
    In one window, nc -l 2000 > outfile , in another - nc localhost 2000 <infile - this is the transfer of the file through a tcp-socket in a continuous stream. (nc is a netcat utility) Listing it in c ++ is lazy. - alexlz
  • one
    so what did you stop at when working with sockets? And what axis? Any libraries use? - AlexDenisov
  • one
    When writing both to a socket and to a file, you have an error . You do not need to write sizeof (buf), but the number of bytes read . Otherwise (if the file size is not a multiple of the buffer size) there will be dirt at the end of the file. - For initial training, the algorithm will come down, but in practice, how will the receiver know that the entire file has been successfully transferred? If the transmitter "dies" ahead of time, the receiver will receive 0 for recv () and think that this is the end of the file. - avp

3 answers 3

@ 1110_debian well, I did not realize that kute is qt. Languages ​​not trained. And about the complete solution for the author of the question - alas. But here half (server part without transfer of a name and so forth. - only data) it seems wrote. @RocketDeath : in a real program, the returned values ​​should be checked, I just have to write with them longer.

 #include <stdlib.h> #include <sys/types.h> #ifdef __WIN32__ #include <winsock2.h> #include <io.h> #include <fcntl.h> #else #include <sys/socket.h> #include <netinet/in.h> #endif #include <stdio.h> #include <string.h> const int qlen = 1; // длина очереди соединений int main(int argc, char *argv[]) { struct sockaddr_in sin, ssin; int ssock, sock, len; unsigned char buf[1000]; #ifdef __WIN32__ WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(2, 0); WSAStartup(wVersionRequested, &wsaData); _setmode(_fileno( stdin ), _O_BINARY ); #endif sock = socket(PF_INET, SOCK_STREAM, 0); memset((char *)&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons((u_short)atoi(argv[1])); bind(sock, (struct sockaddr *)&sin, sizeof(sin)); listen(sock, qlen); ssock = accept(sock, NULL, &len); while(len = fread(buf, sizeof(unsigned char), sizeof buf, stdin)) { send(ssock, buf, len, 0); } #ifdef __WIN32__ closesocket(ssock); closesocket(sock); WSACleanup(); #else close(ssock); close(sock); #endif return 0; } 

The only parameter is the port number. File with stdin (redirection can be used)

  • while (len = fread (buf, sizeof (unsigned char), sizeof buf, stdin)) is the same eternal cycle, here is a mistake somewhere ... - Yaroslav Schubert
  • If an error occurs, or the end-of-file is reached, the return value is a short item count (or zero). . When there is nothing to read (EOF), returns and 0. And kaput cycle. - alexlz
  • Tried to do this while (! Feof (in)) {fread (bufer, 1, sizeof (bufer), in); send (current, bufer, sizeof (bufer), 0); } but fread reads all bytes, not the amount equal to the buffer capacity. - Yaroslav Schubert
  • What is it like? More can you? Moreover, it is necessary to use the fread result if your file length is not a multiple of the bufer size. - alexlz
  • one
    Terrible thing. So in SocketServer.exe, the byte with the code 0x1a is found in the first piece. Only this is hardly what you need. Draw int s = 0; while(len = fread(bufer, 1, sizeof bufer, in) s+=len; printf("%d", s); int s = 0; while(len = fread(bufer, 1, sizeof bufer, in) s+=len; printf("%d", s); and see what happens with the "r" and "rb" modes. - alexlz

alexiz, what is WSAStartup? =) Under Windows with sockets worked only from kute. But I know that in the line and in Windows there are different API for this interaction.

Rocketdeath, break the task into subtasks and you will succeed.

  1. Send to the server some hard-coded string ("Hello" for example)
  2. Read a simple text file into memory (and output the contents to the console, for example).
  3. 1 + 2, read file, sent
  • I do not know who is kute (some kind of Georgian surname), and WSAStartup is msdn.microsoft.com/en-us/library/windows/desktop/… - "nitates use of the Winsock DLL by a process." It should be called in Windows the first of the winsock-calls. And about different - so there is some, quite acceptable common subset. (i.e. will work in both winsock and bsd-sockets. - alexlz
  • Kute is Qt, which is a framework, if you don’t troll me on the wrong record =) well, I saw the link, I know what Google is =) - AlexDenisov

You work in Windows and problems with a binary file.

Open for reading:

 FILE *in = fopen(filename,"rb"); 

read in a loop before EOF block-by-block fread () to the buffer that you will pass through the socket. Read - sent (send), etc. All characters will be read (^ Z too), there will be no additional \ r on. Similarly, to write to the file fopen (..., "wb").

It makes sense to make your own simple file transfer protocol, for example:

 Cli -> имя файла -> Serv Serv -> OK size-in-bytes block-size или No such file Serv -> блок 1 Cli <- читает блок 1 (recv()) пишет его в выходной файл (fwrite()) ... Serv -> блок n 

Read all the bytes - OK.

File size (and its attributes) can be found by calling the stat () function

 #include <sys/stat> по другому символ < ввести не получается 

Something like that. There will be specific questions - ask.

  • Apparently, the author is waiting for a complete solution = \ - AlexDenisov
  • Why) I decide and peacefully observe the answers, scooping the ones I need) - Yaroslav Schubert