I am using a NetworkStream to keep an open TCP/IP connection that messages can be sent across. I receive a message, process it, and then return an ACK. I am working with a site where occasionally I receive the message, but when I go to send the ACK, I get an IOException. Sometimes this lasts for only one or two messages (I can receive the next message), and other times it continues until the service is stopped and restarted.
Below is the code for my NetworkStream without any of the processing:
using (NetworkStream stream = client.GetStream())
{
stream.ReadTimeout = ReadTimeout;
...
if (stream.CanRead && stream.DataAvailable)
bytesRead = stream.Read(receivedBytes, 0, BufferSize);
...
stream.Write(ack, 0, ack.Length);
}
Note that the code loops between reading new messages and sending the ACK.
When I call stream.Write
, I will sometimes get the following exception:
System.IO.IOException: Unable to write data to the transport connection: An established connection was aborted by the software in your host machine. ---> System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine
at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at Framework.Communication.Model.Server.AcceptMessage(IAsyncResult ar)
I have looked this message up and found several sources for it for several different communication methods. It sounds like this is a very generic exception that does not really tell what is happening.
Does anyone know what would cause this, or where I could start looking to narrow down the solution?
You are right to think this is a generic problem, so you will have to be more defensive.
Somethings to consider
SocketException
indicating something went wrong. In a third situation, the remote party is no longer connected (for instance by unplugging the network cable) without any communication between the two parties.
Note : None of this explains the intermittent nature of part of the question (if i'm reading it correctly)
So lets see what the documentation says
NetworkStream.Write Method (Byte[], Int32, Int32)
IOException
- There was a failure while writing to the network.
- An error occurred when accessing the socket. See the Remarks section for more information.
Remarks
If you receive a
SocketException
, use theSocketException.ErrorCode
property to obtain the specific error code, and refer to the Windows Sockets version 2 API error code documentation in MSDN for a detailed description of the error.
So in my mind, as mentioned before you need to be a bit more defensive.
Check for 0 bytes.
Check for errors.
In either of these cases, its probably good practice (and makes sense) to restart the connection again, log the failure, and assume the connection has been closed (or abnormally closed)
Additional resources
Detect closed network connection
**** Detection of Half-Open (Dropped) Connections **** Stephen Cleary