nodejs socket接收粘包问题

使用nodejs的net创建socket连接后,先后连着发送一个登录包和心跳包,应该先后分别接收到两个返回值,但是在nodejs里却只返回了一次,并且这两个值粘在一起了。

而使用python代码大部分情况没有出现粘包现象,但小概率偶尔也粘

原因

python 的 recv() 是阻塞读取,而 nodejs 的 'data' 是异步回调推送

python

data = sock.recv(1024)

阻塞调用:调用时线程停在那里,直到至少有 1 个字节到达就会返回(不足 1024 也一样返回)。
当你第一次 recv() 时,如果内核缓冲区里此刻只有第一段包,Python 会立即返回,不会等第二段到。
所以消息一定会被拆成多次 recv() 调用,每次拿到当时缓冲里已有的部分 → 100% 分成多次 log(只要你的发送是分两次 send 而不是一次性全发的)

nodejs

socket.on('data', chunk => { ... })

'data' 是流模式:数据到达,event loop 把“当时缓冲区的全部内容”一起推给你。
Node.js 这边不会像 Python 的阻塞 recv() 那样中途“提前返回”,它会等到 事件循环 从 OS 拿数据的时候,把 OS 缓冲里当时已经到的所有数据都读出来(两个包已经全到),然后合成一个 chunk 调给你。
这种模式下,如果两个包到达时间非常接近(一般在同一 TCP 拍发回去),Node 很可能一次性全读出来 → 100% 粘包的现象。

总结

Python 另开线程阻塞 recv = “专人盯着” → 直接唤醒,延迟极小。
Node 事件循环 = “统一调度” → 可能稍微晚一点才 read,容易积累数据。
粘包不是 Node 独有,是 TCP 的本质特性。
Python 阻塞只是让多条消息在应用层“分开到”的概率更高,但不能避免。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容