0

This is how I send a file using a NetworkStream.

private void go() { byte[] send = File.ReadAllBytes("example.txt"); ns.Write(send, 0, send.Length); } 

ns is a NetworkStream of course.

Now I would like to know how I could receive and read an incoming NetworkStream?

I know that I need to specify a buffer to read from like this,

ns.Read(buffer,0,buffer.length). 

but which buffer should be there?

1
  • 1
    Send the length of the buffer first and then when receiving, create a byte array of that size Commented Aug 4, 2015 at 12:30

1 Answer 1

3

TCP is a stream based protocol, which means that there is no notation of application messages like in UDP. Thus you cannot really detect by TCP itself where an application message ends.

Therefore you need to introduce some kind of detection. Typically you add a suffix (new line, semicolon or whatever) or a length header.

In this case it's easier to add a length header since the chosen suffix could be found in the file data.

So sending the file would look like this:

private void SendFile(string fileName, NetworkStream ns) { var bytesToSend = File.ReadAllBytes(fileName); var header = BitConverter.GetBytes(bytesToSend.Length); ns.Write(header, 0, header.Length); ns.Write(bytesToSend, 0, bytesToSend.Length); } 

On the receiver side it's important that you check the return value from Read as contents can come in chunks:

public byte[] ReadFile(NetworkStream ns) { var header = new byte[4]; var bytesLeft = 4; var offset = 0; // have to repeat as messages can come in chunks while (bytesLeft > 0) { var bytesRead = ns.Read(header, offset, bytesLeft); offset += bytesRead; bytesLeft -= bytesRead; } bytesLeft = BitConverter.ToInt32(header, 0); offset = 0; var fileContents = new byte[bytesLeft]; // have to repeat as messages can come in chunks while (bytesLeft > 0) { var bytesRead = ns.Read(fileContents, offset, bytesLeft); offset += bytesRead; bytesLeft -= bytesRead; } return fileContents; } 
Sign up to request clarification or add additional context in comments.

3 Comments

thank you very much! and if i would like also to send the name of the file and receive it in the other side? @jgauffin
Send another header indicating the size of the file name. i.e. <FileNameLengthHeader><FileName><BodyLengthHeader><Body>
You could also use the networking library in my Griffin.Framework: github.com/jgauffin/griffin.framework