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

Posted

技术标签:

【中文标题】循环直到使用 BeginConnect(C# 套接字)连接到服务器【英文标题】:Loop until connected to server with BeginConnect (C# sockets) 【发布时间】:2019-01-14 06:56:30 【问题描述】:

我需要一种方法来尝试连接到服务器,直到它成功连接。我已经使用 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 对象 来自此类的相应异步方法。范围 名称:异步结果在 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 回调、对象状态、布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback 回调、对象状态、布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、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(对象 状态,布尔超时)

我尝试捕获 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 回调、对象状态、布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback 回调、对象状态、布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、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(对象 状态,布尔超时)

我对使用套接字还很陌生(而且我只编程了几个月)所以我确定我完全错误地解决了这个问题,所以我很感激任何帮助/建议。

【问题讨论】:

这很可能与服务器连接有关。尝试 ping 它或使用 telnet 看看您是否可以访问它。很可能clientSocket 通过套接字发送请求并等待响应,但从未得到响应,因此抛出异常 服务器在所有其他测试中都运行良好,只有当我尝试以这种方式连接时才会发生这种情况。但是,服务器确实说客户端连接了 10 次,然后立即断开连接。编辑:此外,它适用于 telnet。 【参考方案1】:

由于您尚未发布完整代码,我假设您正在尝试使用全局 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例子,看看吧。如果你修复了,这是你方法的第一步,它应该可以工作。

【讨论】:

以上是关于循环直到使用 BeginConnect(C# 套接字)连接到服务器的主要内容,如果未能解决你的问题,请参考以下文章

win 10 UAP/UWP(通用应用程序)的异步套接字库?

C# TcpClient的Connect超时处理(Timeout)

在 do while 循环内部,我想在 c# 中每 1 分钟执行一次特定代码,直到条件满足

TCP 套接字服务器偶尔会随着时间的推移建立 CLOSE_WAITs 直到无法操作

Socket.BeginConnect 方法

Unity 中的简单套接字服务器