Node.js TCP 传入消息拆分成包

Posted

技术标签:

【中文标题】Node.js TCP 传入消息拆分成包【英文标题】:Node.js TCP incoming message splitting into packages 【发布时间】:2012-02-01 10:59:36 【问题描述】:

通过 TCP 连接在 Node.js 中接收大数据包时遇到问题。 似乎缓冲区中有一个上限设置为大约 55kB。当我收到大量数据(大约 70-80k)时,它会拆分这些数据。

现在,我使用过 UDP 套接字,我知道如何期待 on('data', function()) 事件以及在最终收到消息时如何期待 on('end', function()),TCP 的问题是我从未收到 @987654323 @event,服务器(在 C# 中)从不发送 FIN 数据包。这是因为我需要让套接字保持活动和持续(我们不想关闭它)。

是否有某种方法可以发送 FIN 数据包,从 C# 到 Node.js 的,而无需关闭/关闭套接字?

或者,是否有某种方式可以触发节点本身内部的on('end', function()) 事件?

问候。

编辑: 为了解决这个问题,比如说我有 2 个客户端试图通过 TCP 套接字获取信息。一个先连接,然后收到一个巨大的请求(这里的大小没有问题)。

但是在处理这个请求时,另一个请求执行相同的请求,因为 TCP 连接是通过节点的,所以它们使用相同的套接字。 有什么方法可以区分请求吗?还是我必须为向 TCP 服务器发出的每个请求设置一个套接字?

【问题讨论】:

您知道消息有多大,即消息是否包含自身的大小或有效负载?是否有任何类型的消息结束标记? 为了解决这个问题,现在我们设置了一个消息结束标记,但我们希望有比这更好的解决方案。 问题是TCP是一个streaming协议,数据像流一样流动,消息之间没有内置边界。它可靠且易于使用,但如果不用作纯数据流,通常需要在其上分层的另一个协议。 我明白了,补充一下这个问题,比如说我有 2 个客户端试图通过 TCP 套接字获取信息。一个先连接,然后收到一个巨大的请求(这里的大小没有问题)。但是,在处理这个请求时,另一个请求执行相同的请求,因为 TCP 连接是通过节点,所以它们使用相同的套接字。有什么方法可以区分请求吗?还是我必须为每个完成的请求设置一个套接字?我会将其添加为问题的编辑。 两个客户端的服务器套接字将相同,但定义每个客户端连接的套接字对将不同。服务器上 accept() 返回的套接字对象对于每个连接的客户端都是唯一的,因此很容易区分请求。 【参考方案1】:

UDP 是面向数据包的。您可以发送尽可能多的数据包,最大绝对最大值为 65,507 字节。它是一劳永逸的,没有处理数据包丢失或重新排序的内在机制。

TCP 是面向流的。您的数据将根据包括数据量和传输速率在内的几个因素分成数据包。这大部分超出了您的控制范围,由 TCP/IP 堆栈管理。您得到的回报是有序的数据包序列和一定程度的容错(保证正确的数据包排序,并且 TCP/IP 协议栈对应用程序代码透明地检测和处理丢失/重复的数据包)。

如果您在 node 中的套接字级别工作,您几乎肯定会收到多个回调,每个回调都包含一大块数据。由你自己把它缝合起来。这是一件好事——这意味着您可以定义自己的机制来识别消息边界、数据压缩等。

【讨论】:

PS:接受这个,因为它很好地解释了问题,另外,对于那些可能想知道的人,操作系统处理套接字数据包数据也存在问题(同样的问题也发生在 Flash 中),它将 Windows 7 更新到 SP1 时已修复。【参考方案2】:

我遇到了类似的问题,看来您需要使用两种技术:

    一种解析消息并将其放在一起的方法---我使用了以下答案 [问题]:nodejs - parsing chunked twitter json 您可以为第二个客户端启动一个新的 tcp 连接,或者为每个发出的请求创建一个包含 clientID 的数组。当消息从服务器返回时,您将获取数组中的第一个 clientID 并将消息传递给它们。

【讨论】:

【参考方案3】:

我会说尝试缓冲和追加

【讨论】:

以上是关于Node.js TCP 传入消息拆分成包的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 的有状态的进程间通信

在 node.js 中管理基于命令的 TCP 套接字 API 上的连接

使用 node.js 读取传入的 HTTP 标头

在 Node.js HTTP 服务器上重用 TCP 连接

多台机器上的 Node.js tcp 套接字服务器

如何防止 Node.js 将套接字消息拆分成更小的块