一个tcp例子,解包
发布于 12 年前 作者 guilin 7189 次浏览 最后一次编辑是 8 年前

写了个tcp例子,抛砖引玉

client, 发送一个字符串

var net = require('net');

var socket = net.connect(5002, 'localhost', function() {
    var str='abc';
    var len = Buffer.byteLength(str);
    var buf = new Buffer(len + 2);
    buf.writeUInt16BE(len, 0);
    buf.write(str, 2);
    for(var i=0; i<100; i++) {
      socket.write(buf);
    }
})

server 端,用on message来处理信息。

var net = require('net');

function getDataParser(emmiter) {

  var waiting = 0
    , buf
    , bufOffset
    ;

  function parseData(data, offset) {
    var len = data.length;
    var left = len - offset;
      if(waiting) {
        var toRead = Math.min(left, waiting);
        if(waiting <= left) {
          data.copy(buf, bufOffset, offset, offset + waiting);
          offset += waiting;
          waiting = 0;
          emmiter.emit('message', buf);
          if (offset < len) {
            parseData(data, offset);
          }
        } else {
          data.copy(buf, bufOffset, offset, len);
          waiting -= (len - offset);
        }
      } else {
        waiting = data.readUInt16BE(offset);
        buf = new Buffer(waiting);
        // UINT length is 2
        parseData(data, offset + 2)
      }
  }

  return parseData;
}

function handler(socket) {
  var parseData = getDataParser(socket);

  socket.on('data', function(data) {
      console.log('data');
      console.log(data);
      parseData(data, 0);
  });

  socket.on('message', function(buf) {
      console.log('msg');
      console.log(buf);
  })
}

net.createServer(handler).listen(5002);
4 回复

沒人感興趣啊

這個例子是將包長度放在包頭,保證可以整條整條消息的讀取。 反饋機制是可以的,序列號挺好的,也不會大很多,序列號16位就夠了,循環使用。

如果发过来的包不完整,好像没有校验

对包的整体作一个加法校验放到包头里 当然也可以做crc检验

回到顶部