循环直到使用BeginConnect(C#套接字)连接到服务器

时间:2018-08-07 08:42:12

标签: c# .net sockets asynchronous client

我需要一种尝试连接到服务器直到成功连接的方法。我已经使用Socket.Connect成功完成了此操作,但无法使其与Socket.BeginConnect一起使用。

这是方法:

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; }
}

但是我得到这个错误(多次):

  

System.ArgumentException:未返回IAsyncResult对象   来自此类的相应异步方法。参数   名称:asyncResult位于   System.Net.Sockets.Socket.InternalEndConnect(IAsyncResult asyncResult)   在System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)在   SocketLibrary.Client.TCPClient.ConnectCallback(IAsyncResult ar)位于   System.Net.LazyAsyncResult.Complete(IntPtr userToken)在   System.Net.ContextAwareResult.CompleteCallback(对象状态)位于   System.Threading.ExecutionContext.RunInternal(ExecutionContext   executionContext,ContextCallback回调,对象状态,布尔值   reserveSyncCtx)位于   System.Threading.ExecutionContext.Run(ExecutionContext   executionContext,ContextCallback回调,对象状态,布尔值   reserveSyncCtx)位于   System.Threading.ExecutionContext.Run(ExecutionContext   executeContext,ContextCallback回调,对象状态),位于   System.Net.ContextAwareResult.Complete(IntPtr userToken)在   System.Net.LazyAsyncResult.ProtectedInvokeCallback(对象结果,   IntPtr userToken)在System.Net.Sockets.Socket.ConnectCallback()在   System.Net.Sockets.Socket.RegisteredWaitCallback(对象状态,布尔   超时)   System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object   状态,布尔型timedOut)

我尝试捕获ArgumentException,但随后又出现此错误(多次)

  

未处理的异常:System.NullReferenceException:对象引用   未设置为对象的实例。在   SocketLibrary.Client.TCPClient.ConnectCallback(IAsyncResult ar)位于   System.Net.LazyAsyncResult.Complete(IntPtr userToken)在   System.Net.ContextAwareResult.CompleteCallback(对象状态)位于   System.Threading.ExecutionContext.RunInternal(ExecutionContext   executionContext,ContextCallback回调,对象状态,布尔值   reserveSyncCtx)位于   System.Threading.ExecutionContext.Run(ExecutionContext   executionContext,ContextCallback回调,对象状态,布尔值   reserveSyncCtx)位于   System.Threading.ExecutionContext.Run(ExecutionContext   executeContext,ContextCallback回调,对象状态),位于   System.Net.ContextAwareResult.Complete(IntPtr userToken)在   System.Net.LazyAsyncResult.ProtectedInvokeCallback(对象结果,   IntPtr userToken)在System.Net.Sockets.Socket.ConnectCallback()在   System.Net.Sockets.Socket.RegisteredWaitCallback(对象状态,布尔   超时)   System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object   状态,布尔型timedOut)

我刚开始使用套接字(并且我只从事了几个月的编程工作),所以我确定我将完全犯错,因此我将不胜感激。 / p>

1 个答案:

答案 0 :(得分:0)

由于您尚未发布完整的代码,因此我假设您正在尝试使用全局client对象。在ConnectCallback中,您需要首先检索client对象并将其转换成Socket。因此,在您的情况下,它将是:

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());  
    }  
}  

以上代码取自this MSDN示例,请看一下。如果您修复了该方法的第一步,那么它应该会起作用。