C: send file to socket

孤街醉人 提交于 2021-02-04 10:32:25

问题


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


回答1:


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




回答2:


Fread() in chunks




回答3:


// assumes TCP
#define MTU_SIZE 1500
unsigned char mtu[MTU_SIZE];
int bytes_read;

// if you need a header specifing file size send it here

//Read file contents into buffer
while (( bytes_read = fread(mtu, MTU_SIZE, 1, file)) != EOF )
    if ( send(client, mtu, bytes_read, 0) < bytes_read )
        do_error();

You won't need the header if you're just sending one file. You just close the TCP connection when you're done sending and the when the client receives the EOF then they'll know it's EOF ;-)

You might also find this SO question very illuminating:

Why is writing a closed TCP socket worse than reading one?




回答4:


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



来源:https://stackoverflow.com/questions/5594042/c-send-file-to-socket

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!