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
相关产品推荐
相关产品推荐

