1

写入套接字时,我得到了一个奇怪的结果。我用客户端和服务器编写了一个简单的实验:

服务器.js

var net = require('net');
net.createServer(function (connection) {
  connection.on('data', function (data) {
    console.log('data: ' + data);
  });
}).listen(1337);

客户端.js

var net = require('net');
var client = net.connect({port: 1337}, function () {
  var i = 0;
  function send() {
   client.write('a');
    if (++i < 100) {
      process.nextTick(send);
    } else {
      client.end();
    }
  }
  send();
});

我希望服务器显示 100 行data: a,但我最终得到的data: aaaaaaa行数较少。这socket.setNoDelay()似乎是我想要的,但它似乎没有任何效果。

我错过了什么?

非常感谢,

4

1 回答 1

4

TCP 协议仅发送您在套接字中写入的字节。它们不会被分成消息,这取决于你。如果您想获得 100 行,a则必须定义 100 条单独的消息,并为它们选择一个分隔符。通常人们通过\r\n.

因此,您需要将服务器更改为

var net = require('net');
net.createServer(function (connection) {
  connection.on('data', function (buffer) {
    var data = buffer.toString();
    if (data.indexOf('\r\n') > -1) { // If there's more than one line in the buffer
        var lines = data.split('\r\n'); // Split the lines
        var i = lines.length;
        while (i--) { // This will read your lines in reverse, be careful
            console.log(lines[i]);   // Print each line
        }
    } else {
        console.log(data); // If only one line came through, print it
    }
  });
}).listen(1337);

和你的客户

var net = require('net');
var client = net.connect({port: 1337}, function () {
  var i = 0;
  function send() {
   client.write('a\r\n'); // Notice the \r\n part. This is what will help you separate messages on the server
    if (++i < 100) {
      process.nextTick(send);
    } else {
      client.end();
    }
  }
  send();
});

然后我相信你会得到 100 行a.

这个模块还提供了一种非常有趣的方法,当然ZeroMQ也会在这方面大放异彩,因为它已经有一个很好的协议,可以将东西放入信封并发送它们。

同样有趣的是,但超出了您的问题范围,您发送到一侧套接字的消息将不会以相同的顺序到达服务器。如果您将发送功能更改为

  function send() {
    if (++i < 100) {
      client.write('a'+i+'\r\n');
      process.nextTick(send);
    } else {
      client.end();
    }
  }

您可以看到它们不是按照您发送它们的顺序到达的。

通过“TCP 协议仅发送您在套接字中写入的字节”,我的意思是如果您这样做socket.write("1"); socket.write("2"),您将"12"在服务器上收到,因为那是您在套接字上写入的内容。您必须通过某些东西明确地分隔您的消息,以便服务器可以知道消息何时开始以及消息何时结束。

关于是否按顺序接收东西,您会注意到,如果您删除 process.nexTick 并让您的客户喜欢:

var net = require('net');
var client = net.connect({port: 1337}, function () {
  var i = 100;
  while (i--) {
    client.write('a'+i+'\r\n');
  }
});

您将在服务器上收到两条消息(至少我收到了):第一个数字是 83 - 99,然后是 0 - 82,尽管它们是按顺序编写的。

这是因为 TCP 以某种神奇的方式将其拆分为数据包。第一个包裹实际上比第二个大,所以它最后到达那里。当然,您可以在 wikipedia 页面中阅读有关 TCP 工作原理的更多信息,并且该视频可能会比您需要听到的内容更多,但它有助于理解您正在使用的所有内容。

于 2012-08-19T20:56:20.693 回答