我有一台服务器通过NetworkStream.Read
管理两个客户端。
申请协议是:
ClientMessage [128字节]→来自服务器的响应[128字节]
现在在服务器端:是否可能,MyTcpClient.GetStream().Read()
仅返回< 128字节,虽然来自客户端的所有消息都是128字节长?
我猜这样的客户端消息很短,足以容纳tcp / ip层上的一个数据包 - 但是可能存在某种碎片或随机的情况吗?
NetworkStream.DataAvailable
是正确的属性来抵御这个吗?
经过几个小时的平稳运行后,我有时会遇到奇怪的错误和连接丢失,这就是那种情况。
提前致谢。
答案 0 :(得分:1)
简短回答:
完全无法保证您将在一次Read
通话中收到整个数据包,即使该数据包是在Write
次通话中发送的,也是较小的比网络MTU,即使你实际上是发送到/从loopback接口读取。你不能对这种行为采取任何行动。
Read
的文档明确指出:
实施可以自由返回 字节数少于请求的字节数 流的结尾还没有 达到。
你可以做的事情会像这样(伪代码)
While (true) {
Read from stream
If bytes read == 0 {
Socket was closed (buffer should be empty here)
Break
}
Append read data to persistent buffer
While (buffer.Length >= 128) {
Extract first 128 bytes from buffer (buffer length now reduced by 128)
Process message
}
}
答案 1 :(得分:1)
是否可能,MyTcpClient.GetStream()。Read()仅返回< 128字节
是。您不能假设您对Read()的调用将返回128个字节。
请参阅docs:
读入的总字节数 缓冲区。这可能比 请求的字节数,如果那么多 字节当前不可用,或 零(0)如果流的末尾有 已经到达。
有关如何正确阅读流的信息,请参阅this链接
尝试这样的事情:(传入一个128长度的字节数组)
private static void ReadWholeArray (Stream stream, byte[] data)
{
int offset=0;
int remaining = data.Length;
while (remaining > 0)
{
int read = stream.Read(data, offset, remaining);
if (read <= 0)
throw new EndOfStreamException
(String.Format("End of stream reached with {0} bytes left to read", remaining));
remaining -= read;
offset += read;
}
}