При отправке нескольких сообщений в сокет Node.js tcp они передаются в виде одного сообщения

Чтобы показать простой пример, я хочу отправить несколько сообщений в сокет node.js tcp. Я только хочу отправить второе сообщение, когда первое сообщение полностью отправлено/выведено. Однако даже при ожидании вызова обратного вызова записи сообщения, кажется, отправляются как одно сообщение.

Вот пример кода:

var net = require('net');

var server = net.createServer();

server.on('connection', function(socket){
  socket.write('First Message', function(){
    socket.write('Second Message')
  })
})

var client = new net.Socket();
client.setEncoding('utf8');

server.listen(9999, function(){
  client.connect(9999);
});

client.on('data', function(data){
  console.log('data received on socket:\n' + data);
});

В соответствии с документацией node.js из socket.write, "Опциональный параметр обратного вызова будет выполнен, когда данные окончательно выписаны - это может быть не сразу".

Основываясь на этом, в моем коде второе сообщение должно быть отправлено только тогда, когда данные окончательно выписаны для первого сообщения.

Но записанный вывод:

данные, полученные в сокете:

Первое сообщение MessageSecond

Как я могу отправить это сообщение отдельно?

Ответ 1

TCP не отправляет сообщения "отдельно". TCP - это протокол потока, что означает, что при записи байтов в сокет вы получаете одинаковые байты в том же порядке на принимающей стороне. Нет понятия "границы сообщений" или "пакеты" что-либо в этом роде.

В вашем примере обратный вызов вызывается, когда уровень сокета принимает ваши данные для передачи. Это не означает, что данные были успешно отправлены или даже полностью покинули ваш компьютер. В вашем обратном вызове вы отправляете второе сообщение, но уровень сокета объединяет его с первым сообщением для эффективности, поскольку он не имеет значения для TCP.

Ответ 2

Вам необходимо определить формат для вашего сообщения, чтобы ваш клиент мог определить начало и конец сообщения в потоке сокета. Например, вы можете использовать возврат каретки, чтобы отметить конец сообщения в вашем примере.

Затем вы можете использовать разделенный поток для чтения сообщений отдельно на клиенте.

var net = require('net');
var split = require('split');
var server = net.createServer();

server.on('connection', function(socket){
  socket.write('First Message\n', function(){
    socket.write('Second Message\n')
  })
})

var client = new net.Socket();
client.setEncoding('utf8');

server.listen(9999, function(){
  client.connect(9999);
});

var stream = client.pipe(split());
stream.on('data',function(data){
    console.log(data);
});