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

通过Socket发送超过1024字节数据出现传输错误的原因咨询

问题根因

该问题和1500字节的MTU限制没有关联,和官方文档标注的1048576字节发送缓冲区上限也不冲突。核心错误是你没有处理send()、recv()的返回值:TCP是字节流协议,这两个系统调用不会保证一次性发送/接收你指定的全部长度数据,返回值才代表本次调用实际成功传输的字节数。

当你设置单次发送长度为1024时,数据大概率能一次性写入内核发送缓冲区、或被对端一次性接收完成,所以不会触发问题;当单次长度超过1024时,单次send()可能没有写完所有数据、或单次recv()没有收完所有数据,你直接忽略返回值向下执行,就会出现数据错位,最先受影响的就是作为文件传输元数据的chunk和rest变量,这两个值读错之后后续的文件读写逻辑会完全混乱。

至于官方标注的1M发送缓冲区,它指的是内核暂存应用层待发送数据的最大容量,和单次send()能发送的长度没有直接关系:就算缓冲区总容量有1M,要是当前缓冲区剩余空间不足你传入的发送长度,send()只会返回实际写入缓冲区的字节数,剩余未发送的数据需要你主动调用多次send()补发。

修复方案

你需要封装两个可靠传输的工具函数,保证指定长度的数据被完整传输后再返回:

可靠发送函数

ssize_t send_all(int fd, const void* buf, size_t len) {
    size_t total_sent = 0;
    const char* ptr = static_cast<const char*>(buf);
    while (total_sent < len) {
        ssize_t n = send(fd, ptr + total_sent, len - total_sent, 0);
        if (n <= 0) return n; // 连接关闭或出现错误
        total_sent += n;
    }
    return total_sent;
}

可靠接收函数

ssize_t recv_all(int fd, void* buf, size_t len) {
    size_t total_recv = 0;
    char* ptr = static_cast<char*>(buf);
    while (total_recv < len) {
        ssize_t n = recv(fd, ptr + total_recv, len - total_recv, 0);
        if (n <= 0) return n; // 连接关闭或出现错误
        total_recv += n;
    }
    return total_recv;
}

将你代码中所有的send()、recv()调用替换为上述封装函数即可解决问题。另外你当前代码中perror("Error: ")的调用位置不合理,只有在系统调用返回错误时调用perror才有意义,正常执行时这里会输出无意义的错误提示,建议补充错误判断逻辑后再保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 07:21:00