C:发送文件到套接字

Posted

技术标签:

【中文标题】C:发送文件到套接字【英文标题】:C: send file to socket 【发布时间】:2011-08-01 10:20:22 【问题描述】:

我正在尝试使用套接字发送二进制文件。

        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);

它工作正常,但有些文件太大,我想读取一部分缓冲,发送它,然后读取第二部分,发送它等等。

我尝试使用 fread 和 fgets 获取零件,但失败了 =( 如何正确操作?

UPD:问题在于读取来自客户端的传入请求。我没读过。如果我这样做,就不会发生任何不好的事情

【问题讨论】:

您需要向我们展示如何您尝试过,否则很难回答您失败的原因。应该不会太难... 向我们展示您是如何使用 fread 和 fgets 进行操作的,我们将向您展示如何使其工作。我原以为你可以调用 fread 直到它返回一个与你的计数不同的值,然后在同一个循环中将它写入套接字。 【参考方案1】:

类似:

#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);

但是您还需要发送块数据,并且不能假设您会在一次调用中发送所有数据。

所以send() 必须看起来更像这样:

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

然后您必须准备好在 send() 调用期间处理中断(在这种情况下,您只需要从同一位置重复发送):

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

在 EINTR(希望很少见)的情况下,send 将在下一次循环迭代中重复,并且可能有机会在下一次完成并将数据返回到您的程序

【讨论】:

此外,为了获得最佳网络效率,您应该在fread()+send() 循环期间启用Nagle 算法(TCP_NODELAY)和/或设置TCP_CORK。这样可以将所有文件数据打包到尽可能少的网络数据包中。【参考方案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();

如果您只是发送一个文件,则不需要标题。您只需在完成发送后关闭 TCP 连接,当客户端收到 EOF 时,他们就会知道它是 EOF ;-)

您可能还会发现这个 SO 问题很有启发性:

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

【讨论】:

【参考方案4】:

问题在于读取来自客户端的传入请求。我没读过。如果我这样做,就不会发生任何不好的事情

【讨论】:

以上是关于C:发送文件到套接字的主要内容,如果未能解决你的问题,请参考以下文章

NSOutputStream 发送旧值 - Objective C

C TCP套接字,带有文件发送的回显服务器,发送文件后挂断

使用 C 中的套接字通过 TCP 发送音频文件

c_cpp 发送文件 - c套接字

c_cpp 发送文件 - c套接字

c_cpp 发送文件 - c套接字