C:发送文件到套接字

发布于 2024-10-31 04:42:04 字数 539 浏览 4 评论 0原文

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

        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:问题在于读取来自客户端的传入请求。我没有读它。如果我这样做,不会发生任何不好的事情

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

扬花落满肩 2024-11-07 04:42:04

类似于:

#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 的(希望很少见)情况下,发送将在下一次循环迭代中重复,并且可能有机会完成下一次并将数据返回到您的程序

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

听不够的曲调 2024-11-07 04:42:04
// 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 ;-)

您可能还会发现这个问题非常有启发性:

为什么写入一个封闭的 TCP 套接字比读取一个更糟糕?

// 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?

掀纱窥君容 2024-11-07 04:42:04

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文