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

Node.js net模块多次write数据合并的粘包问题如何解决

问题本质说明

TCP是面向字节流的传输协议,本身不存在「消息边界」的概念,内核会根据Nagle算法、缓冲区大小等机制自动合并/拆分数据,这是TCP的固有特性,不是Node.js net模块的问题,也无法通过配置net模块直接实现单次write对应单次data事件的收发,必须自行在应用层定义数据传输协议来解决粘包、拆包问题。

解决方案:自定义应用层帧协议

最常用且稳定的方案是长度前缀法,每发送一条消息时先附加固定长度的消息体长度字段,接收方按长度精准读取对应字节的内容,完全无需依赖分隔符,同时兼容粘包、拆包两种场景。

实现逻辑

  • 发送端:每发送一条数据前,先写入4字节的无符号整数(存储当前数据的字节长度),再写入实际数据内容
  • 接收端:为每个连接维护独立的接收缓冲区,每次收到新数据就追加到缓冲区,循环执行解析逻辑:
    • 判断缓冲区长度是否≥4字节:不足则等待下一批数据
    • 读取前4字节得到当前消息的实际长度,再判断缓冲区剩余长度是否≥该消息长度:不足则等待下一批数据
    • 截取对应长度作为完整消息处理,剩余内容留在缓冲区等待后续解析

客户端改造代码

const net = require('net');
const client = net.connect({port: 8080}, function() {
  console.log('connected to server!');  
});

const string = "acdefghijklmnopqrstuvwxyz";

// 封装发送函数,自动添加长度前缀
function sendMsg(data) {
  const dataBuf = Buffer.from(data, 'utf8');
  // 4字节存储数据长度,最大支持4GB单条消息
  const lenBuf = Buffer.alloc(4);
  lenBuf.writeUInt32BE(dataBuf.length, 0);
  client.write(lenBuf);
  client.write(dataBuf);
}

setInterval(function(){
  sendMsg(string);
  sendMsg(string);
},1);
setInterval(function(){
  sendMsg(string);
  sendMsg(string);
},1);

服务端改造代码

const net = require('net');
const net_port = 8080;

const server = net.createServer(function(connection){
  // 每个连接维护独立接收缓冲区
  let receiveBuf = Buffer.alloc(0);

  connection.on('data', function(data){
    // 新数据追加到缓冲区
    receiveBuf = Buffer.concat([receiveBuf, data]);

    // 循环解析缓冲区,支持一次解析多条完整消息
    while(receiveBuf.length >= 4) {
      const msgLen = receiveBuf.readUInt32BE(0);
      // 剩余内容不足一条完整消息,退出等待下一批数据
      if(receiveBuf.length < 4 + msgLen) {
        break;
      }
      // 截取完整消息
      const msgContent = receiveBuf.subarray(4, 4 + msgLen).toString('utf8');
      console.log("Received, Length: "+msgContent.length); // 固定输出25
      // 剩余内容留在缓冲区
      receiveBuf = receiveBuf.subarray(4 + msgLen);
    }
  });

  connection.pipe(connection);
});

server.listen(net_port, function() { 
  console.log('server is listening');
});

方案优势

  • 完全规避分隔符法的缺陷,无需担心业务内容包含特殊字符导致解析错误
  • 同时兼容粘包、拆包场景,不管TCP层如何合并/拆分数据,应用层都能精准还原每条消息
  • 解析逻辑简单性能高,无额外的字符串扫描开销

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:36:04