Hi,
I have written some software, one aspect of which is a TCP client. It sends messages to a designated address and port and receives a number of messages in response. This is all working perfectly on some PCs, but on others, it loses connection.
I have done some digging and debugging and it appears to relate to the ReadTimeout/ReceiveTimeout. On the computers that have problems, if no data is received and one of the timeout values is reached, the TCPClient shows as disconnected. On the PCs that work fine, the timeout occurs but the client remains connected.
Here's the code I am using:
private TcpClient client;
private BinaryReader MessageReader;
private BinaryWriter MessageWriter;
private NetworkStream DataStream;
private Thread ClientThread;
private void ConnectTcpClient()
{
//check that client and thread haven't already been instantiated/connected
if ((ClientThread != null && ClientThread.ThreadState != ThreadState.Stopped)
&& (client.Client != null && client.Connected))
{
return;
}
//create and connect client in new thread
ClientThread = new Thread(new ThreadStart(PerformConnection));
ClientThread.Start();
}
private void PerformConnection()
{
//try Connecting on the given ip address
try
{
using (client = new TcpClient()) //assign new tcp client object
{
client.ReceiveTimeout = 20000;
client.SendTimeout = 5000;
ChangeStatusContent("Connecting..."); //invoke to write status to menu on main form
DisconnectFlag = false;
IAsyncResult result = client.BeginConnect(_ethernetPort._IP, _ethernetPort._iPort, null, null);
bool success = result.AsyncWaitHandle.WaitOne(5000, true);
if (!success)
{
client.Close();
ChangeStatusContent("Disconnected");
return;
}
DataStream = client.GetStream();
DataStream.ReadTimeout = 10000;
DataStream.WriteTimeout = 5000;
using (MessageReader = new BinaryReader(DataStream))
{
using (MessageWriter = new BinaryWriter(DataStream))
{
ChangeStatusContent("Connected");
HandleConnection();
MessageWriter.Close();
MessageReader.Close();
DataStream.Close();
client.Close();
ChangeStatusContent("Disconnected");
}
}
}
}
catch (Exception)
{
ChangeStatusContent("Disconnected");
}
}
private void HandleConnection()
{
string message = "";
//loop until DisconnectFlag state changed
do
{
//try reading from the data stream if anything went wrong with the connection break
try
{
while (!message.Contains(Environment.NewLine))
{
message += MessageReader.ReadChar();//read message
}
if (message != "")
{
ChangeTextBoxContent(message);//invoke method to write message to textbox on main form
message = "";
}
}
catch (Exception ex)
{
if (client == null || !client.Connected)
{
ChangeStatusContent("connection Lost");
break; //get out of the while loop
}
}
} while (!DisconnectFlag);
}
I originally had no timeouts, but found that I couldn't get the thread to close as the read call would block. I added the timeouts so that I can set the DisconnectFlag to true when i want to close and join the ClientThread. I'm not sure why some PCs are handling this differently than others, although I believe that the ones with the problem are Windows XP whilst the ones that work are Win7 (the only PC that i was able to reproduce the fault on was WinXP...the others are at a remote clients site).
Any help would be greatly appreciated as this has me stumped at the moment. I don't want to take the timeouts away as then I will be back to a blocking read call which prevents the application closing cleanly once the client is connected.