1

ソケットへの書き込み時に奇妙な結果が得られます。クライアントとサーバーを使用した簡単な実験を作成しました。

サーバー.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()欲しいようですが、効果がないようです。

私は何が欠けていますか?

どうもありがとう、

4

1 に答える 1

4

TCP プロトコルは、ソケットに書き込んだバイトを正確に送信するだけです。それらはメッセージに分割されません。それはあなた次第です。100 行を取得したい場合はa、100 個の個別のメッセージを定義し、それらの区切り文字を選択する必要があります。通常、人々は TCP ソケットに送信されるメッセージを で区切ります\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');
  }
});

サーバー上に 2 つのメッセージが表示されます (少なくとも私は取得しました): 最初は 83 から 99 まで、次に 0 から 82 まで、順番に書き込んだにもかかわらずです。

これは、TCP が何らかの魔法の方法でパケットに分割するためです。最初のパッケージは実際には 2 番目のパッケージよりも大きかったため、最後に到着しました。もちろん、ウィキペディアのページで TCP の仕組みの詳細を読むことができます。このビデオは、おそらく聞く必要がある以上のことを言っているでしょうが、作業しているすべてを理解するのに役立ちます。

于 2012-08-19T20:56:20.693 に答える