File transfer over sockets, final size with fewer bytes

I'm trying to get some file via sockets in C. But the server sends me 64 byte packets for a 1,000,000 byte file, and I get about 999902 bytes in the target file.

while ((n = read(sd, buffer_in, BUFSIZE ))) // BUFSIZE = 64 { if(n<0) { printf("Fail.\n"); fclose(archivo); return -1; } if(fwrite(buffer_in, n, 1, f) !=1 ) { printf("fwrite error.\n"); fclose(archivo); return -1; } bytes+=n; } printf("We received %d bytes", bytes); 

When used over a local TCP / IP socket, it works, but not in a slow connection. I see through debugging that I get a lot of 64 byte chunks and a 30 byte chunk near the EOF. I know that you can get fewer bytes on read (), as the call returns when any data is available (> 1 byte). But this condition should not be caught by time? Should return when n == 0, this is no longer data (EOF).

Thanks for your help.

(EDIT)

Sending the code as follows:

 while (n=read(file_fd, buffer, BUFSIZE)) { write (sdaccept, buffer, n) } 

I know that both read () and write () can return N <BUFSIZE, but should this loop not work properly? I added n and returns 1,000,000, the exact size.

(EDIT II)

Tested with source C with 10673 bytes, gets 10575 without damage, except that the LACKS destination file contains the first 98 bytes !!!

+6
c sockets file-transfer
source share
1 answer

The provided send code ignores the fact that write () (or send ()) on the socket is not required to write the entire buffer.

write () / send () may decide to partially write or not write at all if the underlying subsystem refuses to receive more data (for example, the network subsystem may have a queue for sending data, and this queue is already full). This is very likely with a slow connection.

The sender must check the return value of write () to determine how much data has actually been written and adjusted accordingly.

The entry should be made like this:

 int readAmount; while( readAmount = read(file_fd, buffer, BUFSIZE) > 0 ) { int totalWritten = 0; do { int actualWritten; actualWritten = write (sdaccept, buffer + totalWritten, readAmount - totalWritten); if( actualWritten == - 1 ) { //some error occured - quit; } totalWritten += actualWritten; } while( totalWritten < readAmount ); } 
+11
source share

All Articles