0

I am getting data from the NetworkStream of a TcpClient and I want to write the data into a fixed-length MemoryStream, because I know the size of the data.

I use Stream.CopyToAsync to write the data into the MemoryStream:

var result = new MemoryStream(size);
await ns.CopyToAsync(result);
result.Position = 0;

return result;

Looking at the source code of Stream.CopyToAsync, the method terminates when there is no data in the source stream. In my case, when the network connection is slow or interrupted, my method would return an incomplete MemoryStream.

Can I ignore this possibility or should I read the stream by my own since I know how much data will be sent?

Nico Schreiner
  • 397
  • 5
  • 13
  • `CopyToAsync` doesn't really relate to your problem, I don't think. Would the problem be different if you were reading chunks into a buffer and manually writing them to the `MemoryStream`? It seems to me that the real problem is that you don't know how many bytes you are selecting. – ProgrammingLlama May 08 '20 at 08:27
  • Since I know how many bytes will be sent by the server, I could repeat "read from source, then write into memorystream" until all bytes are received. – Nico Schreiner May 08 '20 at 08:33
  • Then what stops you from checking that `MemoryStream` is the length you expect? If you get 0 bytes as the result of a read, the connection is closed. – ProgrammingLlama May 08 '20 at 08:35
  • I thought that when the connection is closed, `NetworkStream.Read` throws an `ObjectDisposedException`. Correct me if I am wrong but shouldn't it be totally possible that read returns 0 bytes even thought the connection is still open? – Nico Schreiner May 08 '20 at 08:40
  • [`Read` blocks if there is no data (i.e. it waits for data).](https://stackoverflow.com/a/6958290/3181933) – ProgrammingLlama May 08 '20 at 08:40
  • Alright, I didn't know that, thank you for the clarification. Then `CopyToAsync` should be fine in my case. You can add an answer with a link to the source you just provided. – Nico Schreiner May 08 '20 at 08:50

1 Answers1

1

Since NetworkStream.Read will block1 until there is data and only return 0 if the connection is closed, I don't think this will meet your needs any better than CopyToAsync.

Since you already know how much data you're hoping to receive, I recommend just checking that the MemoryStream has the desired length:

var result = new MemoryStream(size);
await ns.CopyToAsync(result);

if (result.Length != size) {
     // it didn't load everything
}

result.Position = 0;

return result;

1 https://stackoverflow.com/a/6958290/3181933

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86