将数据写入Node中的套接字

时间:2012-08-19 19:48:01

标签: node.js

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

server.js

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

client.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()似乎是我想要的,但它似乎没有任何效果。

我错过了什么?

非常感谢,

1 个答案:

答案 0 :(得分:3)

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

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

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

This module也提供了一种非常有趣的方式,当然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以某种神奇的方式将其分组。第一个包实际上比第二个包大,所以它最后到达那里。您当然可以在维基百科页面上阅读有关TCP如何工作的更多信息,this video可能比您需要听到的内容更多,但它有助于理解您正在使用的所有内容。