I have a TCPClient that creates a stream that I read from when DataAvailable.
Every 20 seconds that !DataAvailable I ping the socket with an ACK message to keep the stream from closing.
But I seem to be getting mixed results. It seems like every other time I open the stream(basically restart my Service) I get transport errors.
This is a shortened version of my Connect function:
client = new StreamClient();
client.Connect(new IPEndPoint(clientAddress, senderPort));
stream = client.GetStream();
bool status = SendMessage(seq, sync, MessageTypes.Init);
The SendMessage function does:
if (stream == null) return false;
stream.Write(TransmitBuffer, 0, TransmitMessageLength);
My Close function does:
if (stream != null)
{
SendMessage(seq, sync, MessageTypes.Finish);
stream.Close();
}
stream = null;
client.Close();
client = null;
It is expected that the SendMessage calls will fail occasionally due to nature of the socket.
But sometimes, once I Connect, everything runs fine, no failed messages. But other times the ACK’s will fail. When the ACK’s fail, I call Close, which will force a Connect and validate the other end of the socket is open. If that fails then I know that end is down. But sometimes that call doesn’t fail and then 20 seconds later the ACK does.
Can anyone give me an opinion on why this may happen? Is 20 seconds too long to wait? Am I not closing my end of the socket properly?
The specific error message i’m fighting with is:
Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
And it occurs at stream.Write(TransmitBuffer, 0, TransmitMessageLength);
The main thing I see in your implementation that jumps out at me is that it looks like you’re treating the Stream as the Connection, and it isn’t. Your checks on the Stream instance should instead be checks on the TcpClient instance. I’m not sure if that’s the source of your problem, but it definitely looks strange to me.
Instead of this:
I usually do something more like this:
You should be checking TcpClient.Connected before working with the stream, not the stream itself.
Another thing I would mention is to be sure to always use the async methods to connect, read, and write with your TcpClient. The synchronous ones are easier, but my experience has been that relying on them can get you into trouble.