我不太确定如何在标题中解释我的问题,但我会试着详细说明我的问题。
基本上我正在编写一个非P2P的聊天,但是所有用户都连接到中央服务器,类似于IRC。连接是异步的,几乎完美无缺。主要问题是,当一次将大量数据发送给一个用户(或从一个用户发送到服务器)时,字节可能会合并,从而导致错误。我通过在其余数据前面添加一个包含4位字节的标头来解决这个问题。仍然,字节似乎合并。我也尝试将 NoDelay 设置为 true ,将 DontFragment 设置为 false ;不过,它不起作用。
我猜测问题是当字节合并时,我只处理第一个字节,然后对剩余的字节做任何事情。解决这个问题的最佳方法是什么?
接收回拨代码:http://pastebin.com/f0MvjHag
答案 0 :(得分:2)
这就是他们称之为流的原因。你把字节放在一端,TCP保证它们在远端以相同的顺序出现,没有丢失或重复。任何大于一个字节的东西都是你的问题。
您必须在缓冲区中累积足够的字节才能拥有标头。然后解释它并开始处理其他字节。你可能还剩下几个开始下一个标题。
这是正常行为。当您的应用程序未接收数据时,系统将为您缓冲它。它会在您下次提出请求时尝试移交可用数据。另一方面,大写可能会通过不支持足够帧大小的连接传输。它们将根据需要进行拆分,最终达到最佳状态。
答案 1 :(得分:1)
这通常发生在以紧密间隔发送两个或更多数据包时。 我自己最近遇到了这个问题,我解决它的方法是分离键。然后,您可以对每条消息进行标记。例如,您可以像我一样将ASCII字符#4(传输结束字符)添加到每个正在发送的邮件的末尾。
Write("Message1" + ((char)4).ToString())
Write("Message2" + ((char)4).ToString())
然后,当客户端收到数据时,您可以迭代接收到的数据。当它发现特殊字符时,它知道它是一条消息的结束,并且(可能)是一条新消息的开头。
"Message1(EOT char)Message2(EOT char)"
\n
可能比使用ASCII字符更容易使用。