【问题标题】:Receiving a file with sockets接收带有套接字的文件
【发布时间】:2021-12-16 04:11:24
【问题描述】:

我想在我的 c 程序中通过套接字接收一个文件,为此我创建了一个函数 recvfile_all。它根据参数data 分块接收文件。 struct filedata 定义为

struct filedata {
    struct stat st;
    char filename[FILENAME_MAX];
};

我的函数的代码是-

// Receive a file based on filedata. Return the number of bytes
// left to receive in case of error
size_t recvfile_all(int sock, const struct filedata *data) {
    size_t to_recv = data->st.st_size;     // total data to receive for a file
    size_t recv;                           // length of data to receive once
    char *buffer = malloc(0);              // buffer to hold chunk
    size_t chunk_s = data->st.st_blksize;  // chunk size to receive file in
    size_t supp_to_recv;

    FILE *file = fopen(data->filename, "w");
    if (file == NULL) return to_recv;

    while (to_recv) {
        // receive a chunk if we have more to receive than the size of a
        // single chunk, otherwise receive whatever is left
        recv = to_recv > chunk_s ? chunk_s : to_recv;
        supp_to_recv = recv;
        buffer = realloc(buffer, recv);
        recvall(sock, (char *)buffer, &recv);

        if (recv < supp_to_recv)
            return to_recv - recv;  // return how much is left to receive

        fwrite(buffer, 1, recv, file);  // write what was received to file
        to_recv -= recv;
    }
    fclose(file);
    return to_recv;
}

函数recv_all 是一个类似于Beej 网络编程指南中的send_all 的函数。它只是从套接字接收一些字节。我已经对其进行了多次测试,并且运行良好,我认为此功能不存在错误。它被定义为-

int recvall(int s, char *buf, size_t *len) {
    size_t total = 0;         // how many bytes we've recveived
    size_t bytesleft = *len;  // how many we have left to receive
    size_t n;

    while (total < *len) {
        n = recv(s, buf + total, bytesleft, 0);
        if (n == -1 || n == 0) {
            break;
        }
        total += n;
        bytesleft -= n;
    }

    *len = total;  // return number actually sent here

    return n == -1 ? -1 : 0;  // return -1 onm failure, 0 on success
}

我的功能似乎不起作用。任何想法为什么? 另外,错误肯定不在发送文件的代码中,我已经测试过多次了。

【问题讨论】:

  • 如何它似乎不起作用?应该发生什么?实际发生了什么?当出现错误(在发送者或接收者中)时,您会打印出错误是什么?您是否使用调试器单步执行代码?实际发送的是什么?
  • @Someprogrammerdude 它接收到的垃圾数据混杂了一点点实际应该接收的数据,执行时没有错误
  • recv 是否会返回 -10?您是否尝试过在它发生时打印一些相关信息?以及如何检测“垃圾”数据?你实际上在发送什么?它是 binary 文件还是 text 文件?
  • 循环中的realloc 调用有什么用?为什么没有固定大小的缓冲区来接收数据?这应该会简化recvfile_all 中的许多代码。更简单的代码意味着出现问题或错误的机会更少,同时也更容易调试。
  • recv 不返回 -10。我可以看到收到的数据是垃圾,因为它是一个文本文件。

标签: c sockets


【解决方案1】:

原来功能正常,我是使用链表发送文件,由于之前的错误,服务器接收到客户端将要发送的文件的标题以相反的顺序,纠正修复问题

【讨论】:

    最近更新 更多