2012-08-09 101 views
0

ALL, 我在C#中使用异步套接字。 我的问题是:我想等待回调完成连接,因为我需要立即将信息发送到服务器。是否有可能在异步套接字上等待连接

下面的代码片段:

class InternetConnector 
{ 
    private struct ConnectionData 
    { 
     public Action<Exception> ErrorHandler { get; set; } 
     public Socket Socket { get; set; } 
    } 
    public void ConnectToHost(Action<Exception> errorHandler) 
    { 
     IPEndPoint ip = new IPEndPoint(IPAddress.Parse(connector_host), connector_port); 
     client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     var ConnectionData = new ConnectionData { ErrorHandler = errorHandler, Socket = client }; 
     client.Blocking = true; 
     client.BeginConnect(ip, new AsyncCallback(ConnectCallback), ConnectionData); 
     connectDone.WaitOne(100); 
    } 

    private static void ConnectCallback(IAsyncResult ar) 
    { 
     ConnectionData connectionData = new ConnectionData(); 
     try 
     { 
      connectionData = (ConnectionData)ar.AsyncState; 
      connectionData.Socket.EndConnect(ar); 
      connectDone.Set(); 
      Connected = true; 
     } 
     catch (Exception e) 
     { 
      if (connectionData.ErrorHandler != null) 
       connectionData.ErrorHandler(e); 
     } 
    } 
} 

public partial class Form1 : Form 
{ 
    private bool isRunning = false; 
    private InternetConnector client = new InternetConnector(); 

    private void AsyncErrorHandler(Exception e) 
    { 
     if (status.InvokeRequired) 
     { 
      status.BeginInvoke(new Action(() => AsyncErrorHandler(e))); 
      return; 
     } 
     InternetConnector.Connected = false; 
     isRunning = false; 
     startStop.Text = "Start"; 
     status.ForeColor = Color.Red; 
     status.Text = "Socket Error: " + e.Message; 
    } 

    private void startStop_Click(object sender, EventArgs e) 
    { 
     if (!isRunning || !InternetConnector.Connected) 
     { 
      if (!InternetConnector.Connected) 
      { 
       client.SetAddress(ipAddress.Text); 
       client.SetPort(Convert.ToInt32(connectionport.Text)); 
       client.ConnectToHost(AsyncErrorHandler); 
       status.Text = "Signals Receiver: Connected"; 
       status.ForeColor = Color.Green; 
       startStop.Text = "Stop"; 
       isRunning = true; 
    // if connection successful, send some data and start reading the socket 
      } 
      else 
      { 
       startStop.Text = "Start"; 
       client.DisconnectFromHost(AsyncErrorHandler); 
       isRunning = false; 
      } 
     } 
    } 
} 

我能处理的连接异常。现在我需要处理成功的连接。

谢谢。

回答

1

您可以遵循相同的模式,并提供一个处理程序上的成功,以及对错误被称为:

class InternetConnector 
{ 
    private struct ConnectionData 
    { 
     public Action<Socket> SuccessHandler { get; set; } 
     public Action<Exception> ErrorHandler { get; set; } 
     public Socket Socket { get; set; } 
    } 

    public void ConnectToHost(Action<Socket> successHandler, Action<Exception> errorHandler) 
    { 
     IPEndPoint ip = new IPEndPoint(IPAddress.Parse(connector_host), connector_port); 
     client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     var ConnectionData = new ConnectionData 
     { 
      SuccessHandler = successHandler, 
      ErrorHandler = errorHandler, 
      Socket = client 
     }; 
     client.Blocking = true; 
     client.BeginConnect(ip, new AsyncCallback(ConnectCallback), connectionData); // <-- make sure to use the lower-case connectionData here! :) 
     connectDone.WaitOne(100); 
    } 

    private static void ConnectCallback(IAsyncResult ar) 
    { 
     ConnectionData connectionData = new ConnectionData(); 
     try 
     { 
      connectionData = (ConnectionData)ar.AsyncState; 
      connectionData.Socket.EndConnect(ar); 
      connectDone.Set(); 
      Connected = true; 
      if (connectionData.SuccessHandler != null) 
       connectionData.SuccessHandler(connectionData.Socket); 
     } 
     catch (Exception e) 
     { 
      if (connectionData.ErrorHandler != null) 
       connectionData.ErrorHandler(e); 
     } 
    } 
} 

传递是成功的处理程序必须Action<Socket>委托匹配函数的签名,这看起来像这样:

void MySuccessHandler(Socket socket) 
{ 
    // do stuff with the connected socket..   
    Console.WriteLine("Connected to {0}", socket.RemoteEndPoint);   
} 

void MyErrorHandler(Exception e) 
{ 
    Console.WriteLine("Connection error {0}", e.Message);   
} 

... 

myConnector.ConnectToHost(MySuccessHandler, MyErrorHandler);