javascript - 写入套接字非常快会导致连接缓冲区

标签 javascript node.js sockets

我有这个代码来测试服务器,

var client = net.connect({port: 3000}, onConnected);

client.setNoDelay(false);

function onConnected() {
    while (true) {
        client.write('hello');
    }
}

使用debug模块,我看到每个请求都有 0 毫秒,考虑到它位于同一台机器上,这是预期的。

服务器应该接收<Buffer 68 65 6c 6c 6f>但服务器实际上收到:

<Buffer 68 65 6c 6c 6f 68 65 6c 6c 6f 68 65 6c 6c 6f 68 65 6c 6c 6f 68 65 6c 6c 6f 68 65 6c 6c 6f 68 65 6c 6c 6f 68 65 6c 6c 6f 68 65 6^Cc 6c 6f 68 65 6c 6c 6f 68 ...>

奇怪的行为?实际上不是,如果我理解正确的话,发生这种情况是因为写入没有立即刷新,导致它在实际发送之前被加入。

但问题是如何解决这个问题并实际接收正确的字节,即使写入套接字的速度非常快。

一个想法是让所有写入的数据前面加上大小。然后从该大小读取并从那里剪切缓冲区。但问题是我该怎么做?

我认为我不能用这样的东西做到这一点:

socket.on('data', function(data) {
  var len = data[0];

  // hmmmm
})

所以,

  • 有没有办法逐字节读取流并 chop 到每个数据包第一个字节上指定的每个长度?
  • 更好的选择?
  • 还是我没有捕获重点?

最佳答案

TCP 套接字实现流通信,而不是数据包。这意味着您可以先写入 3 个字节,然后再写入 3 个字节,而接收方可以在第一次读取时获取 5 个字节,然后在第二次读取时获取 1 个字节。

如果您想发送数据包,您需要自己在流中对其进行编码,标准方法是首先发送数据包大小,然后发送数据包本身。例如

var szbuf = Buffer(2); // max packet size is 65535
szbuf[0] = msg.size & 255;
szbuf[1] = msg.size >> 8;
write(szbuf); // Send the size
write(msg);   // Send the message

读取器首先需要读取 2 个字节,计算大小,然后读取该字节数来获取消息。

如果您需要使用基于消息的通信,可能会使用更高级别的库,例如 0MQ是一个更好的主意。

如果您只编写服务器并且协议(protocol)不包含消息边界(例如,类似 ascii telnet 的协议(protocol)的换行符),那么很难(不可能)提供可靠的消息传递,因为写入和读取TCP 不尊重边界,并且互联网上的延迟可以是任意的。

这意味着客户端无法知道消息是否完整。

关于javascript - 写入套接字非常快会导致连接缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24837580/

相关文章:

javascript - 在javascript中添加到具有指定索引的数组

node.js - Node : curly brackets in require statement throwing error

c - 套接字的文件描述符不起作用

javascript - anchor 回页面并打开内容

javascript - jQuery ajax 表单不起作用

node.js - 如何在 Express Generator 应用程序骨架中使用 Node 集群模块

javascript - 如何在循环内完成异步函数后调用函数?

sockets - 如何通过 tcp 套接字传输大数据

java - SSLSocket 客户端的输入流无法从服务器接收任何内容

javascript - 如何将键盘绑定(bind)添加到轮播功能? -jQuery