当我写一个网络流两个单独的字节数组时,我有时候得不到第一个字节数组。 那是为什么?
例如,如果失败,则不会收到标题,有时是另一方的Read()
byte[] header = msg.getByteHeader();
byte[] data = msg.getByteData();
clientStream.Write(header, 0, header.Length);
clientStream.Write(data, 0, data.Length);
clientStream.Flush();
然而这成功了
NetworkStream clientStream = tcpClient.GetStream();
byte[] header = msg.getByteHeader();
byte[] data = msg.getByteData();
int pos = 0;
Array.Copy(header, 0, message, pos, header.Length);
pos += header.Length;
Array.Copy(data, 0, message, pos, data.Length);
clientStream.Write(message, 0, message.Length);
这就是我的Read()外观
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4);
//string stringData = Encoding.ASCII.GetString(message, 0, bytesRead);
len = BitConverter.ToInt32(message, 0);
//MessageBox.Show(len.ToString());
bytesRead = clientStream.Read(message, 0, 5 + len);
}
答案 0 :(得分:1)
我认为这是一个时间问题。首次打开套接字通信和从缓冲区读取第一个数据之间存在延迟。这不是瞬间的。您可以在尝试读取之前查询网络流的DataAvailable布尔状态。如果没有DataAvailable,请将线程称为100毫秒,然后再次尝试读取。
答案 1 :(得分:1)
您可以通过注释掉第二次写入来查看它,然后查看您的服务器是否发送了任何数据。
你的阅读机制看起来非常脆弱,我同意西蒙福克斯认为这看起来不正确。为什么第二次读取要求len + 5字节?我原以为它只是len字节,因为第一次读取是4个字节字节。
如果我是你,我会在标题传输的开头添加一个分隔符。这将允许您的接收器扫描它以确定数据包的开始。使用TCP,您通常会将捆绑的传输或多个传输捆绑到同一个数据包中。如果您总是依赖于获取所请求的字节数,那么一旦部署到互联网等真实网络,事情就会出错。
或者切换到UDP,你可以依赖每个数据包进行一次传输。
答案 2 :(得分:0)
你是不是在第二次通话的第一次通话中覆盖了你所读到的内容? Read的第二个参数是开始存储数据读取的偏移量,两个调用都使用0,所以第二个会覆盖第一个...