Search code examples
c#winformsnetworkingtcpclient

How to set the timeout for a TcpClient?


I have a TcpClient which I use to send data to a listener on a remote computer. The remote computer will sometimes be on and sometimes off. Because of this, the TcpClient will fail to connect often. I want the TcpClient to timeout after one second, so it doesn't take much time when it can't connect to the remote computer. Currently, I use this code for the TcpClient:

try
{
    TcpClient client = new TcpClient("remotehost", this.Port);
    client.SendTimeout = 1000;

    Byte[] data = System.Text.Encoding.Unicode.GetBytes(this.Message);
    NetworkStream stream = client.GetStream();
    stream.Write(data, 0, data.Length);
    data = new Byte[512];
    Int32 bytes = stream.Read(data, 0, data.Length);
    this.Response = System.Text.Encoding.Unicode.GetString(data, 0, bytes);

    stream.Close();
    client.Close();    

    FireSentEvent();  //Notifies of success
}
catch (Exception ex)
{
    FireFailedEvent(ex); //Notifies of failure
}

This works well enough for handling the task. It sends it if it can, and catches the exception if it can't connect to the remote computer. However, when it can't connect, it takes ten to fifteen seconds to throw the exception. I need it to time out in around one second? How would I change the time out time?


Solution

  • You would need to use the async BeginConnect method of TcpClient instead of attempting to connect synchronously, which is what the constructor does. Something like this:

    var client = new TcpClient();
    var result = client.BeginConnect("remotehost", this.Port, null, null);
    
    var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1));
    
    if (!success)
    {
        throw new Exception("Failed to connect.");
    }
    
    // we have connected
    client.EndConnect(result);