2009-09-08 90 views
2

嘿,我与C#异步套接字编程做恶梦。你能指点我一本指南或教程,或者一本深入解释异步编程的书。如果可能包含如何在开始发送/接收函数中使用状态参数来处理多个客户端。C#套接字编程

+4

而不是针对套接字编程,你有没有考虑过WCF?有了WCF中可用的功能,您只需要在非常特殊的情况下针对套接字进行编码。 – 2009-09-08 07:38:41

+1

从最近的经验来看,如果你想做微乎其微的MSDN预留,.net中的套接字编程会令人难以置信的令人沮丧。强烈建议你看看任何其他可以为你做的事情。 – annakata 2009-09-08 07:54:08

+0

检查[this](http://www.codeguru.com/csharp/csharp/cs_network/sockets/article.php/c7695) – 2009-09-08 07:39:40

回答

4

服务器可以通过这样的场景进行组织:客户端连接的分离线程侦听端口。


/// Async server 
public class AsyncServer 
{ 
    /// Server socket 
    private Socket _serverSocket; 

    /// Element for sync wait 
    private static ManualResetEvent _connectionMutex = 
       new ManualResetEvent(false); 

    /// Client handler 
    private ClientManager _clientManager; 

    public AsyncServer(string ipAddrees, int port) 
    { 
     try 
     {    
      this._serverSocket = new Socket(AddressFamily.InterNetwork, 
       SocketType.Stream, ProtocolType.Tcp); 

      this._serverSocket.Bind(
       new IPEndPoint(IPAddress.Parse(ipAddrees), port)); 

     } 
     catch (Exception ex) 
     { 
      throw new Exception("Server Init Error.", ex); 
     } 
    } 

    private BackgroundWorker _listenThread = new BackgroundWorker(); 

    public void Start() 
    { 
     this._clientManager = new ClientManager(this._clientConnections); 

     this._listenThread.WorkerReportsProgress = true; 
     this._listenThread.WorkerSupportsCancellation = true; 
     this._listenThread.DoWork += 
       new DoWorkEventHandler(ListenThread_DoWork); 

     this._listenThread.RunWorkerAsync(this._serverSocket); 
    } 

    /// Thread for listening port 
    private void ListenThread_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Socket serverSocket = (Socket)e.Argument; 

     serverSocket.Listen(100); 

     while (true) 
     { 
      // reset mutex 
      _connectionMutex.Reset(); 

      serverSocket.BeginAccept(
      new AsyncCallback(this.AcceptCallback), this._serverSocket); 

      // waiting for the next connection 
      _connectionMutex.WaitOne(); 
     } 
    } 

    /// List of client connections 
    private List _clientConnections = new List(); 

    public int ConnectionsCount 
    { 
     get { return this._clientConnections.Count; } 
    } 

    /// Callback method for handling connections 
    private void AcceptCallback(IAsyncResult asyncResult) 
    { 
     _connectionMutex.Set(); 

     Socket serverSocket = (Socket)asyncResult.AsyncState; 
     Socket clientSocket = (Socket)serverSocket.EndAccept(asyncResult); 
     this._clientConnections.Add(clientSocket); 

     this._clientManager.HandleClient(clientSocket); 
    } 

} 

方法AcceptCallback(IAsyncResult的asyncResult)手柄所有新的客户端连接并转移到ClientManager,其创建为每个客户端单独的线程。



    public class ClientManager 
    {  

     private List _clientProcessors = new List(); 


     private List _connections;  

     public ClientManager(List connections) 
     { 
      this._connections = connections; 
     } 

     /// Handling of client connection  
     public void HandleClient(Socket clientSocket) 
     { 
      BackgroundWorker clientProcessor = new BackgroundWorker(); 
      clientProcessor.DoWork += new DoWorkEventHandler(ClientProcessing); 

      this._clientProcessors.Add(clientProcessor); 

      List args = new List(); 
      // 
      // args.Add(...);   

      clientProcessor.RunWorkerAsync(args); 
     }  

     private void ClientProcessing(object sender, DoWorkEventArgs e) 
     { 
      // reading args 
      List args = (List)e.Argument;   

      ProtocolSerializer serializer = new ProtocolSerializer(); 

      try 
      { 
       while (socket.Connected) 
       {    
        // ... 

       } 
      } 
      catch (SocketException) 
      { 
       // ... 
      } 
      catch (Exception) 
      { 
       // ... 
      } 
     } 
    }