1

我不太确定如何在标题中解释我的问题,但我会尝试详细说明我的问题。

基本上我正在编写一个不是 P2P 的聊天,但所有用户都连接到中央服务器,类似于 IRC。连接是异步的,几乎可以完美运行。主要问题是,当一次将大量数据发送给一个用户(或从一个用户发送到服务器)时,字节可能会合并,从而导致错误。我通过在其余数据前面添加一个包含数据长度的 4 字节标头来解决此问题。不过,字节似乎合并了。我也尝试将NoDelay设置为true并将DontFragment设置为false;仍然,它不起作用。

我猜问题是当字节合并时,我只处理第一个字节,然后对剩余的字节不做任何事情。解决这个问题的最佳方法是什么?

接收回调码: http: //pastebin.com/f0MvjHag

4

2 回答 2

3

这就是为什么他们称之为流。您将字节放入一端,TCP 保证它们在远端以相同的顺序输出,不会丢失或重复。任何大于一个字节的东西都是你的问题。

您必须在缓冲区中累积足够的字节才能拥有您的标头。然后解释它并开始处理额外的字节。您可能还剩下一些可以开始下一个标题。

这是正常行为。当您的应用程序未接收数据时,系统将为您缓冲它。下次您提出请求时,它将尝试传递可用数据。另一方面,大型写入可能会通过不支持足够帧大小的连接。它们将根据需要进行拆分,并最终以点点滴滴的形式到达。

于 2012-08-03T22:52:23.697 回答
2

这通常发生在两个或多个数据包以接近的间隔发送时。我最近自己也遇到了这个问题,我解决它的方法是使用分离键。然后,您可以标记每条消息。例如,您可以像我一样将 ASCII 字符 #4(传输结束字符)添加到正在发送的每条消息的末尾。

Write("Message1" + ((char)4).ToString())
Write("Message2" + ((char)4).ToString())

然后,当客户端接收到数据时,就可以对接收到的数据进行迭代。当它找到那个特殊字符时,它就知道这是一条消息的结尾,并且(也许)是一条新消息的开始。

"Message1(EOT char)Message2(EOT char)"

\n可能比使用 ASCII 字符更容易使用。

于 2012-08-03T22:56:29.980 回答