读取NetworkStream不会提前流

时间:2011-10-26 19:31:27

标签: c# stream networkstream

我有一个客户端 - 服务器应用程序,其中服务器发送一个4字节的整数,指定下一次传输的大小。当我在客户端读取4字节整数(指定FILE_SIZE)时,下次读取流时,我得到FILE_SIZE + 4个字节读取。

从此流读取时是否需要将偏移量指定为4,或者是否有办法自动推进NetworkStream以使我的偏移量始终为0?

SERVER

NetworkStream theStream = theClient.getStream();

//...
//Calculate file size with FileInfo and put into byte[] size
//...

theStream.Write(size, 0, size.Length);
theStream.Flush();

客户端

NetworkStream theStream = theClient.getStream();

//read size
byte[] size = new byte[4];
int bytesRead = theStream.Read(size, 0, 4);

...

//read content
byte[] content = new byte[4096];
bytesRead = theStream.Read(content, 0, 4096);

Console.WriteLine(bytesRead); // <-- Prints filesize + 4 

2 个答案:

答案 0 :(得分:6)

右;找到了; FileInfo.Lengthlong;致电:

binWrite.Write(fileInfo.Length);

写入8个字节, little-endian 。然后你通过以下方式阅读:

filesize = binRead.ReadInt32();

little-endian 会给你相同的值(至少32位)。但是,在流中没有使用4 00个字节(来自long的高字节) - 因此4字节不匹配。

使用以下其中一项:

  • binWrite.Write((int)fileInfo.Length);
  • filesize = binRead.ReadInt64();

答案 1 :(得分:1)

NetworkStream肯定会进步,但在这两种情况下,你的阅读都是不可靠的;经典的“读取已知内容量”将是:

static void ReadAll(Stream source, byte[] buffer, int bytes) {
  if(bytes > buffer.Length) throw new ArgumentOutOfRangeException("bytes");
  int bytesRead, offset = 0;
  while(bytes > 0 && (bytesRead = source.Reader(buffer, offset, bytes)) > 0) {
    offset += bytesRead;
    bytes -= bytesRead;
  }
  if(bytes != 0) throw new EndOfStreamException();
}

使用:

ReadAll(theStream, size, 4);
...
ReadAll(theStream, content, contentLength);

另请注意,解析长度前缀时需要注意字节顺序。

我怀疑你根本就没有阅读完整的数据。