0
votes

I need a method that attempts to connect to the server until it successfully connects. I've done so successfully with Socket.Connect but I can't get it to work with Socket.BeginConnect.

This is the method:

public void Start()
{
    while (clientSocket == null || !clientSocket.Connected)
    {
        try
        {
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            clientSocket.BeginConnect(serverEndPoint, new AsyncCallback(ConnectCallback), null);
        }
        catch (SocketException)
        {
            clientSocket.Close();
            Start();
        }
        catch (Exception) { throw; } 
    }
}

private void ConnectCallback(IAsyncResult ar)
{
    try
    {
        clientSocket.EndConnect(ar);
        clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
    }
    catch (Exception) { throw; }
}

But I get this error (multiple times):

System.ArgumentException: The IAsyncResult object was not returned from the corresponding asynchronous method on this class. Parameter name: asyncResult at System.Net.Sockets.Socket.InternalEndConnect(IAsyncResult asyncResult) at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult) at SocketLibrary.Client.TCPClient.ConnectCallback(IAsyncResult ar) at System.Net.LazyAsyncResult.Complete(IntPtr userToken) at System.Net.ContextAwareResult.CompleteCallback(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.ContextAwareResult.Complete(IntPtr userToken) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) at System.Net.Sockets.Socket.ConnectCallback() at System.Net.Sockets.Socket.RegisteredWaitCallback(Object state, Boolean timedOut) at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object state, Boolean timedOut)

I tried catching the ArgumentException but then I got this error (multiple times again)

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object. at SocketLibrary.Client.TCPClient.ConnectCallback(IAsyncResult ar) at System.Net.LazyAsyncResult.Complete(IntPtr userToken) at System.Net.ContextAwareResult.CompleteCallback(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.ContextAwareResult.Complete(IntPtr userToken) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) at System.Net.Sockets.Socket.ConnectCallback() at System.Net.Sockets.Socket.RegisteredWaitCallback(Object state, Boolean timedOut) at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object state, Boolean timedOut)

I'm fairly new to working with sockets (and I've only been programming for a couple of months) so I'm sure I'm going about this entirely wrong so I'd appreciate any help/suggestions.

1
It's most likely something with connection to server. Try to ping it or use telnet to see if you can reach it. Most likely clientSocket send request via sockets and awaits response but never gets one hence the exception is thrown - Fabjan
The server has worked fine with every other test, only when I try to connect in this manner does it happen. However, the server does say that the client is connecting like 10 times and then disconnecting immediately afterward. Edit: Also, it works with telnet. - xoltia

1 Answers

0
votes

Since you haven't posted complete code, I am assuming you are trying to use global client object. In the ConnectCallback, you need to first retrieve and typecast the client object into a Socket. So in your case, it would be:

private static void ConnectCallback(IAsyncResult ar) 
{  
    try 
    {  
        // Retrieve the socket from the state object.  
        client = (Socket) ar.AsyncState;
        //In case, you are using local client object
        //Socket client = (Socket) ar.AsyncState;

        // Complete the connection.  
        client.EndConnect(ar);  

        Console.WriteLine("Socket connected to {0}",  
            client.RemoteEndPoint.ToString());  

        // Signal that the connection has been made.  
        connectDone.Set();  
    } catch (Exception e) 
    {  
        Console.WriteLine(e.ToString());  
    }  
}  

The above code is taken from this MSDN example, have a look at it. If you fix, the first step in your approach, it should work.