You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于TCP的服务器向客户端发送文件异常求助

TCP文件传输数据丢失排查指南

嘿,刚接触Socket编程遇到这种问题太正常啦!我帮你梳理几个最容易踩的坑,你对照着检查下你的server.c代码:

  • 忘记传递文件大小,客户端无法判断接收终点
    TCP是字节流协议,客户端没法自动知道什么时候该停止接收。你得先把文件的总大小(比如用4字节的long类型)发给客户端,让它明确需要接收的字节总数,再循环接收直到凑够这个数量。
    示例代码片段:

    // 服务器端先发送文件大小
    long file_size = lseek(fd, 0, SEEK_END); // 获取文件大小
    lseek(fd, 0, SEEK_SET); // 重置文件指针到开头
    send(client_fd, &file_size, sizeof(file_size), 0);
    
    // 客户端对应逻辑:先接收文件大小
    long file_size;
    recv(server_fd, &file_size, sizeof(file_size), 0);
    // 再循环接收file_size字节的数据
    
  • 未处理send/recv的返回值
    别以为写了send(client_fd, buffer, BUFFER_SIZE, 0)就一定能把所有数据发出去!send和recv的返回值是实际传输的字节数,可能小于你传入的长度(比如网络拥堵时)。必须循环调用直到所有数据都发送/接收完成。
    服务器端发送文件内容的正确写法:

    char buffer[1024];
    long bytes_sent = 0;
    while (bytes_sent < file_size) {
        int read_len = read(fd, buffer, sizeof(buffer));
        if (read_len == -1) { perror("read file failed"); break; }
        int sent_len = send(client_fd, buffer, read_len, 0);
        if (sent_len == -1) { perror("send data failed"); break; }
        bytes_sent += sent_len;
    }
    
  • 文件打开模式错误
    如果传输的是二进制文件(比如图片、压缩包),Linux下用O_RDONLY没问题,但Windows下必须加上O_BINARY标志,否则会自动转义换行符,导致文件内容损坏、长度不符。统一用二进制模式更稳妥。

  • 发送完成后未通知客户端结束
    服务器发完文件后如果没关闭连接或发送结束信号,客户端会一直卡在recv里等待更多数据。你可以在发送完所有数据后调用shutdown(client_fd, SHUT_WR),告诉客户端“没有更多数据了”,客户端收到recv返回0时就知道可以停止接收了。

  • 标准IO缓冲区未刷新
    如果你用了fread/fwrite这类标准IO函数而不是系统调用read/write,记得在发送前调用fflush(fp),不然数据可能还停在用户态缓冲区里,没真正发送到网络。

你可以先从这几个点入手排查代码,要是还是解决不了,把完整的server.c贴出来,我再帮你仔细分析!

内容的提问来源于stack exchange,提问作者Deepesh Meena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:47:52