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

C语言Socket文件收发问题:客户端仅接收首行如何修复?

问题解决:Socket传输TXT文件仅接收第一行的修复方案

问题根源

  1. 客户端仅执行一次recv,只能获取服务器首次发送的一行数据,后续服务器发送的内容未被接收
  2. 服务器固定发送T_MAX字节(而非实际读取的有效数据长度),可能导致冗余数据干扰
  3. 服务器用!feof(Log)作为循环条件,存在逻辑缺陷,会触发最后一次无效发送

修复后的服务器代码

FILE *Log = fopen("Log.txt", "r");
if (!Log) {
    printf("[SERVER] 打开文件失败\n");
    return 1;
}

char ms[T_MAX];
// 用fgets返回值判断读取是否成功,替代feof的错误逻辑
while (fgets(ms, T_MAX, Log) != NULL) {
    // 发送实际读取的有效数据长度,而非固定T_MAX字节
    size_t send_len = strlen(ms);
    if (send(client_socket, ms, send_len, 0) < 0) {
        printf("[SERVER] ERROR -> %d\n", WSAGetLastError());
        closesocket(servidor_socket);
        closesocket(client_socket);
        fclose(Log);
        WSACleanup();
        return 1;
    }
}
fclose(Log);

服务器修改说明

  • 用fgets(...) != NULL作为循环终止条件:fgets读取到文件末尾或失败时返回NULL,是判断文件读取完成的正确方式
  • 发送strlen(ms)长度的数据:避免发送缓冲区中未使用的空字符,减少冗余传输
  • 增加文件打开失败的判断,提升代码鲁棒性

修复后的客户端代码

char ms[T_MAX];
int recv_len;
// 循环接收直到服务器关闭连接或出现错误
while ((recv_len = recv(socket_aplication, ms, T_MAX - 1, 0)) > 0) {
    ms[recv_len] = '\0'; // 手动添加字符串终止符,避免printf输出乱码
    printf("%s", ms);
}

// 处理接收错误的情况
if (recv_len < 0) {
    printf(" ERROR -> %d\n", WSAGetLastError());
    closesocket(socket_aplication);
    WSACleanup();
    return 1;
}

客户端修改说明

  • 循环调用recv:TCP是流式协议,服务器多次发送的数据可能被合并或拆分,必须循环接收直到连接关闭(recv返回0)
  • 手动添加'\0':recv不会自动添加字符串结束符,直接printf会读取缓冲区外的垃圾数据
  • 缓冲区预留1字节给终止符:recv长度设为T_MAX - 1,避免缓冲区溢出

额外注意事项

如果传输大文件,建议先发送文件总长度,客户端先接收长度再接收对应字节数,这种方式比依赖连接关闭更可靠。

内容的提问来源于stack exchange,提问作者Ponce Francoo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:20:34