缓冲区,套接字和Node.js

4
我正在尝试在Node.js中利用TCP套接字与Lua程序进行通信。我遇到了两个问题,首先是缓冲区。

缓冲区 据我所知,当从套接字向您的代码提供数据时,它将是迄今为止接收到的所有数据(流而不是数据包)。因此,当您读取接收到的数据时,它可能会与发送的数据不一致。

例如,接收到的数据 { schools : ["Long

与发送的数据 { schools : [{"Longwood", "Hillbrow"}] }

解决这个问题的方法是将数据放入“缓冲区”并通过您用于显示该信息结束的任何方法对其进行拆分。通常出现的是换行符。

我的问题如下:

  1. 如果缓冲区中有两个或更多完整的数据段,您该如何处理?使用for循环吗?
  2. 相同的问题似乎存在于数据离开套接字时。但是我注意到在其他代码示例中,人们在写入套接字之前使用Node.js Buffer。为什么不用于传入的数据?
  3. 如果写入的数据超过了可以处理的范围,Node会为您处理吗,还是需要自己想出一种方法。

最后,我似乎误解了数据方面的内容。是否所有发送和接收的数据都需要转换为二进制并返回?我希望只来回发送JSON数据。我认为我的困惑就在这里。例如:

var myQuestion = "Is this acceptable and will I encounter any issues?
socket.write(myQuestion);

非常感谢您的时间。


PS: 我想为这个冗长的问题致歉。在浏览了各种论坛、组和其他帖子两天后,我仍然不理解,所以我想或许有人可以用我能理解的方式来解释一下! :) - Chris Evans
2个回答

5
  1. 是的,你可能最终会得到几个数据部分。这完全取决于你在两端编写的代码。
  2. 我不太明白你所说的“在写入之前使用缓冲区”的意思。缓冲区只是纯二进制数据,它们用于传入和传出的数据。Node通常也接受字符串进行发送,并假设它们是UTF8编码(如果没有给定编码)。如果调用setEncoding,则还可以在接收时获取字符串。
  3. 操作系统对TCP套接字上的传入数据有缓冲区,当缓冲区已满(由node过于缓慢地清空)时,它将停止接受数据包直到有空间。

首先,Buffer是二进制的。缓冲区只是一组字节,没有其他东西。可以从字符串创建缓冲区,在某些情况下node会自动执行此操作。在您的情况下,我建议您调用socket.setEncoding('utf8')。这将自动将传入的数据转换为字符串以简化解析。

至于处理和拆分数据,则取决于您。TCP仅提供按发送顺序到达的字节流。正如您所说,您可以收集字节,并在接收到换行符时,将其前面的所有内容作为JSON解析。这应该可以正常工作。您可以使用任何不会出现在JSON中的字符。只要进行JSON序列化的程序不添加换行符,那么就可以了。当发出“数据”时,您可以检查字符串是否有换行符,如果没有,则将其添加到先前接收到的任何数据中,如果找到它,则拆分它并添加现有数据。


非常感谢您的回复。我已经重写了问题二,希望它更加清晰明了。我还添加了一个socket.write示例。在发送之前,我需要将字符串转换为二进制吗?还是Node会处理所有这些? - Chris Evans
太棒了!关于缓冲区,您可以在此处看到我所说的示例:https://github.com/Overtorment/NoobHub/blob/master/server/node.js 我不确定如果Node已经接受一个字符串是否会带来附加好处。 - Chris Evans
1
@ChrisEvans 明白了。在这种情况下,数据接收后会被复制到一个单独的缓冲区中。该缓冲区不直接用于发送或接收数据。它用作解析数据的缓存。Node接受字符串是因为否则你会得到更多的样板文件,所以这是有道理的。 - loganfsmyth

1

缓冲区用于发送和接收的信息。接收到的数据可能会被分段,正如您所注意到的那样。将这些数据正确地拼接回来总是由您的代码完成。

完全有可能在缓冲区中接收到两个数据块。通常,您会有一种定界符(例如新行,就像您提到的那样)。我的做法是:

  1. 当数据到达时,将其连接到一个已接收数据缓冲区的末尾。
  2. 有一个函数从该缓冲区读取,根据逻辑包定界符进行拆分。
  3. 验证逻辑包。
  4. 如果该包有效且完整,则向您的代码的更高级部分引发事件,表示已接收到完整的信息。使用解析为普通对象的JSON引发此事件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接