Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#
Tip/Trick

Execute System.Net.Sockets.Socket.Connect Method with Timeout Controlled by System.Threading.Timer

Rate me:
Please Sign up or sign in to vote.
4.80/5 (2 votes)
10 Dec 2013CPOL3 min read 15.1K   312   4  
Connect to remote socket via System.Net.Sockets.Socket.Connect method with timeout controlled by System.Threading.Timer

Introduction

When we need to send messages to a remote host via Socket, we must determine differences between:

  1. if we want to know the possibility of a connection and
  2. if we want to actually connect to the remote host.

If we want to know the availability of a remote host, we can use BeginConnect method from System.Net.Sockets.Socket class, which begins an asynchronous request for a remote host connection, otherwise, if we want to establish a connection to the host in order to send data immediately, we need the Connect method from the same class.

The purpose of this tip is to show how an asynchronous timeout managed by System.Threading.Timer works while trying to connect to a remote socket using System.Net.Sockets.Socket Connect method.

The need to develop a timeout this way comes up when I needed to send data to a remote host in a synchronous way, I had to check first if the sockets were enabled to receive that data, not only if it were available.

That's why I decided to use the Connect method instead of the BeginConnect method. The Connect method, as can be read in MSDN, "Establishes a connection to a remote host" while the BeginConnect method "Begins an asynchronous request for a remote host connection". By implementing the Connect method and by controlling the Exceptions correctly, you can get a synchronous status of your connection with remote socket, and decide in real time what to do when an error occurs, either keep trying to connect for a certain amount of time or abort the mission.

Using the Code

The code included is divided in three projects: JRINCServerSocket: a server socket simulator, Test_JRINCSocketTimeout: an NUnit test project, and JRINCSocketTimeout: the project that does the job.

To mount the test environment, NUnit for framework 2 needs to be installed in the system in order to run the test project, otherwise you can reference the JRINCSocketTimeout from any other project you want and use the methods as shown in test project (Test_JRINCSocketTimeout) Program.cs class.

JRINCSocketTimeout Project

The JRINCSocketTimeout project has only one class named SocketTimeout.cs which has two methods:

execASYNC method

Executes BeginConnect method from System.Net.Sockets.Socket to begin an asynchronous request to the host. An important test you can do is trying to connect to a server that doesn't have a socket listening, in this case the method must return true because BeginConnect method is not connecting initially to send data, it only begins the communication which only tell us that the server exists and is available.

C#
public static bool execASYNC(string IPHost, int port, int timeOut)
{
    #region TIMER //only for visual purposes
    connectTimeout = timeOut;
 
    // Initialize the timer instances and delegates for timer control.
    tmrCbk = new TimerCallback(timer);
 
    tmr = new Timer(tmrCbk);
    tmr.Change(1000, 1000);
    #endregion TIMER
 
    // Creates the socket object.
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 
    try
    {
        // Try to BEGIN an asynchronous request for the remote host connection.
        IAsyncResult result = socket.BeginConnect(IPHost, port, null, null);
 
        bool success = result.AsyncWaitHandle.WaitOne(timeOut * 1000, true);
 
        if (!success)
        {
            socket.Close();
            throw new ApplicationException("Failed to connect server.");
        }
        else
        {
            // Stops timer by changing interval to infinite
            tmr.Change(Timeout.Infinite, Timeout.Infinite);
        }
 
        return success;
    }
    finally
    {
        socket.Close();
    }
}
execByTimer method

Executes Connect method from System.Net.Sockets.Socket to establish a connection to a remote host. You can test by trying to connect to a host that doesn't have a socket listening, the returned value must be an error and false when the timer reaches the configured timeout, because the Connect method is trying to establish a connection constantly until the timer goes out. If you start the simulator before the timer expires, then you would see the application connects to host successfully.

C#
public static bool execByTimer(string IPHost, int port, int timeOut)
{
    // Creates the socket object.
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    try
    {
        connectTimeout = timeOut;
 
        // Initialize the timer instances and delegates for timer control.
        tmrCbk = new TimerCallback(timer);
 
        tmr = new Timer(tmrCbk);
        tmr.Change(1000, 1000);
 

        // While loop checks the connectTimeout variable, which is decreased by timer.
        while (connectTimeout > 0)
        {
            try
            {
                // Try to ESTABLISH a connection to the remote host.
                socket.Connect(IPHost, port);
                // Stops timer by changing interval to infinite
                tmr.Change(Timeout.Infinite, Timeout.Infinite);
                // Breaks the while loop, once connected.
                break;
            }
            // Control SocketExceptions to avoid principal process to stop, 
            // and retry to connect next time in the while loop.
            catch (SocketException se)
            {
                // Write exception message.
                Console.WriteLine(se.ErrorCode + ": " + se.Message);
            }
        }
 
        // Return final socket state.
        return socket.Connected;
    }
    finally
    {
        //always close the socket connection.
        socket.Close();
    }
}
timer method

Is a delegate method executed by System.Threading.Timer that decreases the timeout variable that represents the timeout of the sync connection.

C#
// Control the timeout variable.
private static void timer(object state)
{
    // Writes actual value of connectTimeout.
    Console.WriteLine(connectTimeout);
 
    // Decreases connectTimeout variable.
    connectTimeout--;
 
    // Checks connectTimeout to stop timer.
    if (connectTimeout <= 0)
    {
        Timer timer = (Timer)state;
        timer.Change(Timeout.Infinite, Timeout.Infinite);
    }
}

JRINCServerSocket project

JRINCServerSocket is a WinForms project that emulates a server that enables a socket listener.

Image 1

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Venezuela Venezuela
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --