I am developing a simple application for sending files over TCP using the TCPListener and TCPClient classes. Here is the code that sends the file.
Stop is a volatile boolean that helps stop the process at any time, and WRITE_BUFFER_SIZE can be changed at runtime (another mutable)
while (remaining > 0 && !stop) { DateTime current = DateTime.Now; int bufferSize = WRITTE_BUFFER_SIZE; buffer = new byte[bufferSize]; int readed = fileStream.Read(buffer, 0, bufferSize); stream.Write(buffer, 0, readed); stream.Flush(); remaining -= readed; // Wait in order to guarantee send speed TimeSpan difference = DateTime.Now.Subtract(current); double seconds = (bufferSize / Speed); int wait = (int)Math.Floor(seconds * 1000); wait -= difference.Milliseconds; if (wait > 10) Thread.Sleep(wait); } stream.Close();
and this is the code that handles the receiver side:
do { readed = stream.Read(buffer, 0, READ_BUFFER_SIZE); // write to .part file and flush to disk outputStream.Write(buffer, 0, readed); outputStream.Flush(); offset += readed; } while (!stop && readed > 0);
Now that the speed is low (around 5 Kbit / s), everything works fine, but by increasing the speed, the size of the receiver becomes more likely to raise a SocketException when reading from the stream. I assume this is due to closing the remote socket before all the data can be read, but what is the right way to do this? When should the sending client close?
I have not found good examples of file transfers on google, and the ones I found have a similar implementation of what I'm doing, so I think I'm missing something.
Edit: I get this error "Unable to read data from transport connection." This is an IOException whose internal exception is a SocketException.
I added this to the sender function, but still getting the same error, the code never reaches stream.close (), and of course tcpclient never closes ... so I'm completely lost.
buffer = new byte[1]; client.Client.Receive(buffer); stream.Close();