I have two parts, a client and a server. And I try to send data (size > 5840 Bytes) from the client to the server and then the server sends the data back. I loop this a number of times waiting a second between each time. Sometime the server application crash, the crash seems very random the error:
Unhandled Exception: System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. --->
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 s ize)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 s ize)
at TCP_Server.Program.Main(String[] args)
Client code (This is inside the loop):
try
{
Int32 port = 13777;
using (TcpClient client = new TcpClient(ip, port))
using (NetworkStream stream = client.GetStream())
{
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
var data = GenerateData(size);
sw.Start();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
// Buffer to store the response bytes.
data = new Byte[size];
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
sw.Stop();
Console.WriteLine(i + ": Done transporting " + size + " bytes to and from " + ip + " time: " +
sw.ElapsedMilliseconds + " ms");
// Close everything.
stream.Close();
client.Close();
}
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
sw.Reset();
Server code:
Byte[] bytes = new Byte[size];
// Enter the listening loop.
for (int i = 0; i < numberOfPackages; i++)
{
using (TcpClient client = server.AcceptTcpClient())
using (NetworkStream stream = client.GetStream())
{
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
// Loop to receive all the data sent by the client.
while ((stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Send back a response.
stream.Write(bytes, 0, size);
}
client.GetStream().Close();
client.Close();
}
Console.WriteLine("Receive data size " + size);
}
I have used wireshark to monitor the tcp packages sent and found that a TCP RST is sent from the client to the server before the program crashes. So I assume the problem is that the the RST is not handles correctly. There is no firewall between the client and the host so that is not the problem.
The wireshark files for both the Client and Server is here: https://www.dropbox.com/sh/ctl2chq3y2c20n7/AACgIJ8IRiclqnyOyw8sqd9La?dl=0
So either I need to get rid of the TCP RST or I need my server to handle it in some way and not crash.
I have tried to use longer waiting time but it does not help. If the data is below 5840 Bytes I do not get any crashes, what I know of.
Any suggestions or ideas?
EDIT: Thanks to the answers I got it to work with the following changes:
Server:
// Loop to receive all the data sent by the client.
int k = 0;
while (k < size)
{
int bytesRead = stream.Read(bytes, 0, bytes.Length);
k += bytesRead;
}
// Send back a response.
stream.Write(bytes, 0, size);
And the same when receiving on the client side. Since I first want to send all data and then let the server respond this works for my application.