1

Consider the following program:

using System;
using System.Diagnostics;
using System.Net.Sockets;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      Socket sock = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );

      try
      {
        Stopwatch watch = new Stopwatch();
        watch.Start();

        IAsyncResult res = sock.BeginConnect("localhost", 7000, null, null);

        res.AsyncWaitHandle.WaitOne( 5000 ); // 5 sec timeout

        watch.Stop();
        Console.WriteLine("Elapsed ms: " + watch.ElapsedMilliseconds);

        if (!sock.Connected) {
          sock.Close();
          Console.WriteLine("Failed to connect server.");
        }
      }
      catch (System.Exception ex) {
        Console.WriteLine(ex.Message);
      }
    }
  }
}

Console Output:

Elapsed ms: 1014
Failed to connect server.

I would have expected for BeginConnect to try to establish the connection for about 5 seconds, whereas the wait always returns after just 1 second. Why?

Martin85
  • 308
  • 4
  • 13
  • Please take a look at this [thread][1] [1]: http://stackoverflow.com/questions/1062035/how-to-config-socket-connect-timeout-in-c-sharp – Romano Zumbé Jun 27 '13 at 11:33

1 Answers1

1

The socket does not try to reestablish connection on it's own. What you have done so far will mean you will close the socket if it is still in the connection phase. But if the server actively refuses the connection for instance or something similar your socket will know quite soon about it. To check for that you need to get the error from the IAsyncResult, there you can see why did it fail. If you want to actively try to reconnect, then you have to implement your own logic that will check the result and create a new socket if needed within some time period and tries to connect again.

Ilya Chernomordik
  • 27,817
  • 27
  • 121
  • 207
  • Well the point is that there is no such server, i.e. the only error I can think of would be a timeout. And I wonder how to increase this timeout value. – Martin85 Jun 27 '13 at 13:08
  • Did you try ConnectAsync or just Connect? Do you get any errors in the completed event or an exception if calling connect? If you call ConnectAsync, you can check SocketAsyncEventArgs.SocketError in the callback. – Ilya Chernomordik Jun 27 '13 at 13:46
  • Connect yields: `Elapsed ms: 1012 No connection could be made because the target machine actively refused it 127.0.0.1:7000` So the operation fails after the same amount of time. It seems that the OS is actively refusing the connection as there is no such port open (yet). Is there a way to configure the socket such that it will retry forever until the connection could be established? ( with plain OS / socket functions w/o use of threads ). – Martin85 Jun 28 '13 at 05:40
  • So you have actually the problem that I have described (target machine actively refused). Meaning that the solution is also the one that I have described. I am afraid there is no built-in way to achieve what you want. You have to wrap your method in try catch (by the way, I guess you did not have an exception because you did not call EndConnect) and create a new socket and try to connect again and add logic to check for number of times or timeout depending on what you need. – Ilya Chernomordik Jun 28 '13 at 07:26
  • By the way, I think that it would be better not to try to reconnect. If you get an exception from socket layer - it's unlikely that timeout will help. If it's likely that the first attempt fails and one of the consequent does not - I suggest that you try to reconnect 3 times for instance instead. And if you need a retry forever (I have it my system), then you need to do a while true loop with reconnect, just don't forget to introduce timeout before trying to reconnect. – Ilya Chernomordik Jun 28 '13 at 07:28