Search code examples
c#socketswinsocknonblocking

C# Non-blocking Socket.Connect()


I choose not the use the asynchronous calls since it requires a callback, I'm just curious if there's a way to solve this by utilizing Unix-alike non-blocking socket method: Poll(), as Asyn is created specifically for the Windows environment. I'm researching if this could be done without asynchronous.

To be noted: NON-BLOCKING != ASYNCHRONOUS:)

Therefore I have the following approach by turning off the blocking flag of socket & Poll() method:

    try
    {
        IPEndPoint hostEp = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000);
        Socket hostSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        hostSock.Blocking = false;
        hostSock.Connect(hostEp);

    }
    catch (Win32Exception se)
    {
        if (ex.ErrorCode == 10035) // WSAEWOULDBLOCK is expected, means connect is in progress
        while (true)
        {
            Console.WriteLine("Connecting in progress");
            bool connected = hostSock.Poll(1000000, SelectMode.SelectWrite);
            if (connected)
            {
                Console.WriteLine("Connected");
                break;
            }

        }
    }

But then SelectMode.SelectWrite doesn't seems reinitiates an connection attempts for me. So, what's the problem? And how could I solve this? Should I use Select() instead of Poll()?


Solution

  • Just use the asynchronous methods (ConnectAsync()), they're meant for this. Don't use exceptions for program logic.

    You can synchronously Connect() a TCP socket without blocking:

    Manual:

    The Connect method will block, unless you specifically set the Blocking property to false prior to calling Connect. If you are using a connection-oriented protocol like TCP and you do disable blocking, Connect will throw a SocketException because it needs time to make the connection.

    You can use SocketException.ErrorCode to obtain the specific error code. After you have obtained this code, refer to the Windows Sockets version 2 API error code documentation in the MSDN library for a detailed description of the error.

    If the error returned WSAEWOULDBLOCK, the remote host connection has been initiated by a connection-oriented Socket, but has not yet completed successfully. Use the Poll method to determine when the Socket is finished connecting.

    But that is exactly what your code does, so that should just work.