7

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

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

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

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

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

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

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

4

3 回答 3

14

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

如果您需要接收单个“块”数据,可靠地做到这一点的最简单方法是在其前面加上长度(例如,作为 32 位值)。您读取长度(注意即使是这些字节可以拆分为多个数据包),然后重复读取(无论是同步还是异步),记下您每次读取了多少,直到您读取了所有数据。

于 2009-04-20T16:32:46.103 回答
5

阅读9.2.4

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

于 2009-04-20T16:33:18.317 回答
0

添加到约翰的答案:

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

tcpChannel.Read(buffer, offset, imagesize);
于 2009-06-06T22:21:46.980 回答