C: send file to socket

21,014

Solution 1

the trouble was in reading incoming request from client. I didnt read it. If i do it, nothing bad happens

Solution 2

Something like:

#define CHUNK_SIZE 512

char file_data[CHUNK_SIZE];
//or
char *file_data = malloc(CHUNK_SIZE);

size_t nbytes = 0;
while ( (nbytes = fread(file_data, sizeof(char), CHUNK_SIZE)) > 0)
{
    sent = send(client, file_data, nbytes, 0);
}

But you also need to send the data in chunks, and cannot assume that you'll send all of it in one call.

So that send() would have to look more like this:

    int offset = 0;
    while ((sent = send(client, file_data + offset, nbytes, 0)) > 0) {
            offset += sent;
            nbytes -= sent;
    }

And then you have to be prepared to handle interrupts during the send() call (in which case you'll just need to repeat the send from the same position):

    int offset = 0;
    while ((sent = send(client, file_data + offset, nbytes, 0)) > 0
          || (sent == -1 && errno == EINTR) ) {
            if (sent > 0) {
                offset += sent;
                nbytes -= sent;
            }
    }

In the (hopefully rare) case of EINTR, the send would be repeated on the next loop iteration, and would probably have chance to complete next time and return data to your program

Solution 3

Fread() in chunks

Share:
21,014
spe
Author by

spe

Updated on March 14, 2020

Comments

  • spe
    spe about 4 years

    I`m trying to send binary file using socket.

            FILE *file;
            char *file_data;
            file = fopen(filepath, "rb");
    
            //Allocate memory
            file_data=(char *)malloc(fileLen+1);
    
            //Read file contents into buffer
            fread(file_data, fileLen, 1, file);
            fclose(file);
    
            sent = send(client, file_data, strlen(header)+fileLen, 0);
    

    It works OK, but some files a too large and I want to read a part to buffer, send it, then read the second part, send it and so on.

    I tried to get parts using fread and fgets, but i failed =( How to do it correctly?

    UPD: the trouble was in reading incoming request from client. I didnt read it. If i do it, nothing bad happens

    • unwind
      unwind about 13 years
      You need to show us how you tried, otherwise it's hard to answer why you failed. It shouldn't be too hard ...
    • mdm
      mdm about 13 years
      Show us how you were doing it with fread and fgets, we'll show you how to make it work. I would have thought that you could just call fread until it returns a value different to your count, and in the same loop write it to the socket.
  • Radostin Stoyanov
    Radostin Stoyanov about 5 years
    In addition, for the best network efficiency, you should enable Nagle's algorithm (TCP_NODELAY) and/or set TCP_CORK during the fread()+send() loop. That will enable packing all the file data into as few network packets as possible.