当我通过tcp发送数据包时,它被分成两个数据包

时间:2009-04-20 16:30:39

标签: c# tcp packets mtu

我正在使用服务器 - 客户端模型在C#中开发应用程序,其中服务器将带有位图的字节数组发送到客户端,客户端将其加载到屏幕中,向服务器发送“OK”,以及服务器发送另一个图像,依此类推。

图像缓冲区的长度变化,通常在60kb到90kb之间,但我看到它并不重要。如果我将客户端和服务器放在同一台计算机上,使用localhost,一切正常。服务器执行beginSend,客户端执行endReceive并传输整个缓冲区。

但是,我现在正在无线网络中对此进行测试,结果如下:

  • 服务器发送图像。
  • 调用客户端上的回调函数data_received,但只读取1460个字节(MTU - 为什么?不应该只在UDP中?)
  • 再次调用客户端上的回调函数data_received,现在使用缓冲区的其余部分(1000字节或100千字节)...

总是这样,接收到第一个包含1460字节的数据包,然后第二个数据包包含其余数据包。

我可以通过加入收到的两个字节数组来解决这个问题,但这似乎不对。我甚至不确定为什么会这样。这是对网络的一些限制吗?为什么C#不等待传输整个数据?我的意思是,它是TCP,我不应该担心它,对吧?

无论如何,任何帮助都会很棒! 干杯

3 个答案:

答案 0 :(得分:14)

这是TCP - 您应该将数据视为。您不应该关心流如何被分解成数据包,或者对它做出假设。

如果需要接收单个“块”数据,可靠的最简单方法是在其前面加上长度(例如,作为32位值)。你读取长度(注意甚至那些字节可以分成多个数据包),然后重复读取(无论是同步还是异步)记录你每次读取多少,直到你读完所有数据。

答案 1 :(得分:5)

阅读9.2.4

  

在剖析应用层协议时,您不能假设每个TCP数据包只包含一个应用层消息。一个应用层消息可以分成几个TCP数据包。

答案 2 :(得分:0)

加入John的回答:

int offset = 0;
int imagesize = 512;
byte[] buffer = new byte[512];

tcpChannel.Read(buffer, offset, imagesize);