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

调用recv函数时是否需要对接收缓冲区指针做偏移处理?

关于recv两种写法的正确性说明
  • 首先可以明确给出结论:你担心的问题确实存在,你看到的第二种recv写法是错误的,你的写法则是符合「累计接收满指定长度数据存入同一缓冲区」需求的正确实现。

两种写法的核心差异

recv函数的第二个参数是内核写入接收数据的内存起始地址,第三个参数是本次调用允许写入的最大字节数:

  1. 你的写法每次传入buf + n作为起始地址:新接收的数据会从已有数据的末尾开始写入,同时第三个参数传入剩余可用长度len - n避免缓冲区溢出,完全符合累计接收的逻辑,只要加上错误判断就可以正常使用。
  2. 你看到的第二种写法每次都传入buf作为起始地址:后续recv调用返回的数据会直接从缓冲区头部开始覆盖之前的内容,累加的n只是统计了总共收到的字节数,但缓冲区里只会保留最后一次调用recv收到的数据,前面的内容全部丢失,完全无法实现「收满len字节存在buf里」的需求。

为什么会有大量错误示例流传?

很多示例把两种不同的使用场景搞混了:
如果业务不需要把所有接收的数据攒在同一个缓冲区,而是每次收到数据就立即处理(比如即时打印、写入文件、转发到其他套接字),正确的写法应该是这样的,和你看到的错误写法有本质区别:

char buf[1000];
int n;
// 这里不会累加n,也不会用n < len作为循环条件
while((n = recv(socket, buf, sizeof(buf), 0)) > 0) {
    // 立即处理本次收到的n个字节,处理完后buf的内容就不需要保留了
    fwrite(buf, 1, n, output_fp);
}

很多不负责任的教程抄代码的时候漏了处理逻辑,又错误加上了n += recv和n < len的循环条件,才产出了你看到的错误示例。

你的写法的优化建议

目前你的写法缺少异常处理逻辑,建议补充recv返回值的判断:

  • 返回-1:表示发生了系统错误,需要根据errno判断是临时中断还是致命错误,直接跳出循环做错误处理
  • 返回0:表示对端已经正常关闭了连接,此时不可能再收到剩余的数据,直接跳出循环处理半开连接的情况

内容的提问来源于stack exchange,提问作者Arthur A.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:54:03