我目前正在使用tcp / ip套件。我正在编写一个程序来加密发件人端的文件并在接收方进行解密。我在使用网络流的长度初始化我的字节数组时遇到了这个异常。这是我的代码:
if (client.Connected)
{
NetworkStream binarystream = client.GetStream();
byte[] receivebytes = new byte[binarystream.Length];
binarystream.Read(receivebytes, 0, receivebytes.Length);
Stream file = File.OpenWrite(saveFileDialog1.FileName);
file.Write(receivebytes, 0, receivebytes.Length);
file.Close();
binarystream.Close();
}
控制层次结构确保client.GetStream()
返回的流在构成二进制流实例之前已经用过。我得到的例外情况包含:
byte[] receivebytes = new byte[binarystream.Length];
它表示流不支持搜索操作。这是什么意思?
答案 0 :(得分:7)
这是Stream的正常状态。你需要在春天像一条小沙漠河流那样进行精神上的模拟,像溪流一样涓涓细流的水。你不知道什么时候会干涸,需要一个天气预报,忠实地预测它什么时候会停止下雨。
这样的天气预报确实存在。没有问题,如果它实际上是一个MemoryStream,它可以访问所有字节,这样它可以可靠地告诉你什么时候它干了。或者FileStream,现在操作系统的文件系统可以提供预测。文件数据的目录条目记录文件的长度。
TCP流变得更加困难。 TCP协议本身根本不提供信息。您只能继续调用套接字的Read()方法,当它返回0时,您就知道它已停止下雨。
这通常需要在TCP之上构建协议。非常常见的HTTP协议就是一个很好的例子。它确实为您提供了预测,它是HttpWebRequest.ContentLength。或者你自己制作,标准技术是让发射机首先写入4个字节,说明后面有多少数据。但NetworkStream并不适合特定的协议实现,它为通用网络流建模。你必须自己添加天气预报。
答案 1 :(得分:1)
要确定流的长度,您需要能够读到它的末尾(即您Seek
到最后)。由于这是一个网络流,您不能只这样做,因此您遇到的错误。您需要继续将字节读入缓冲区,直到流结束,然后才能知道有效负载的长度。这是一个建议:
if (client.Connected)
{
NetworkStream binarystream = client.GetStream();
Stream file = File.OpenWrite(saveFileDialog1.FileName);
byte[] buffer = new byte[10000];
int bytesRead;
while (binarystream.DataAvailable)
{
bytesRead = binarystream.Read(buffer, 0, buffer.Length);
file.Write(buffer, 0, bytesRead);
}
file.Close();
binarystream.Close();
}
请注意,我还建议为每个流实例添加using
语句,因为这可以保证即使在读/写时抛出异常也会正确关闭流。然后,您可以删除对Close
的显式调用。