Чтение NetworkStream не продвигает поток - PullRequest
3 голосов
/ 26 октября 2011

У меня есть клиент-серверное приложение, в котором сервер передает 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 ]

6 голосов
/ 27 октября 2011

справа;нашел это;FileInfo.Length является long;Ваш вызов:

binWrite.Write(fileInfo.Length);

записывает 8 байтов, little-endian .Затем вы читаете это обратно через:

filesize = binRead.ReadInt32();

, которое little-endian даст вам то же значение (по крайней мере для 32 бит)Тем не менее, у вас есть 4 00 байтов, не использованных в потоке (из старших байтов long) - отсюда и 4-байтовое несовпадение.1019 *binWrite.Write((int)fileInfo.Length);

filesize = binRead.ReadInt64();
1 голос
/ 26 октября 2011

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);

обратите внимание также, что вам нужно быть осторожным с порядком байтов при анализе префикса длины.

Я подозреваю, что вы просто не читаете полные данные.

...