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

ARM平台下C语言Socket send返回29200,大JSON响应截断问题

解决C语言流式Socket send()截断数据的问题

嘿,我之前做Socket编程时也踩过一模一样的坑!你碰到的29200字节截断问题,本质是对TCP流式Socket的send()方法理解不到位,咱们一步步拆解解决:

核心原因:send()并非一次性发送所有数据

TCP是字节流协议,send()的作用是把你提供的数据尽可能多地拷贝到内核的发送缓冲区里,而不是直接把数据发送到网络。当内核缓冲区剩余空间不足时(比如这次刚好剩29200字节),send()就会返回实际拷贝的字节数,剩下的数据需要你后续再次调用send()来发送。这个29200只是当时内核缓冲区的可用空间大小,是环境相关的随机值,没有特殊含义。

正确解决方案:循环调用send()直到全部数据发送完成

你需要封装一个send_all()函数,循环调用send(),累计已发送的字节数,直到所有数据都被提交到内核缓冲区。示例代码如下:

#include <errno.h>
#include <sys/socket.h>

ssize_t send_all(int sockfd, const void *buf, size_t total_len, int flags) {
    size_t sent_bytes = 0;
    const char *data_ptr = (const char *)buf;

    while (sent_bytes < total_len) {
        ssize_t current_sent = send(sockfd, data_ptr + sent_bytes, total_len - sent_bytes, flags);
        
        if (current_sent == -1) {
            // 处理可重试的错误,比如被信号中断
            if (errno == EINTR) {
                continue;
            }
            // 其他错误(比如连接断开),返回失败
            return -1;
        }

        sent_bytes += current_sent;
    }

    // 返回总发送字节数
    return sent_bytes;
}

用这个函数替代直接调用send(),就能保证所有数据都被提交到内核发送缓冲区。

额外注意事项

  • 检查HTTP响应头的正确性:确保你返回的HTTP响应中Content-Length字段的值和实际JSON数据的字节数完全一致。如果Content-Length设置错误,浏览器可能会提前终止接收或者一直等待,导致你误以为是send()的问题。
  • 不要依赖调整内核缓冲区大小:虽然可以用setsockopt()设置SO_SNDBUF来增大发送缓冲区,但这只是缓解问题,不能从根本上解决——总有数据量超过缓冲区的情况。循环发送才是通用且可靠的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:10:22