2010-04-25 43 views
3

我正在C#中的客戶端/服務器應用程序,我需要得到異步套接字工作,所以我可以一次處理多個連接。從技術上講,它現在是這樣運作的,但是在跑步3分鐘後我得到了OutOfMemoryException。 MSDN說使用WaitHandlerWaitOne()socket.BeginAccept(),但它實際上並沒有讓我這樣做。當我試圖在代碼中這樣做時,它說WaitHandler是一個抽象類或接口,我不能實例化它。我想也許我試試一個靜態參考,但它沒有WaitOne()方法,只是WaitAll()WaitAny()。主要的問題是在文檔中沒有提供完整的代碼片段,所以你實際上看不到他們的「等待處理程序」來自哪裏。它只是一個名爲allDone的變量,它在代碼片段中也有Reset()方法,這是一個等待處理程序不具備的方法。C#異步網絡IO和OutOfMemoryException

在他們的文檔中進行了深入研究之後,我發現Threading名稱空間中的AutoResetEvent有一些相關的事情。它有一個WaitOne()Reset()方法。所以我嘗試了while(true) { ... socket.BeginAccept(...); ... }。不幸的是,這使得它一次只能連接一個連接。所以我不確定要去哪裏。這裏是我的代碼:

class ServerRunner 
    { 
     private Byte[] data = new Byte[2048]; 
     private int size = 2048; 
     private Socket server; 
     static AutoResetEvent allDone = new AutoResetEvent(false); 

     public ServerRunner() 
     { 
      server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      IPEndPoint iep = new IPEndPoint(IPAddress.Any, 33333); 
      server.Bind(iep); 
      Console.WriteLine("Server initialized.."); 
     } 

     public void Run() 
     { 

      server.Listen(100); 
      Console.WriteLine("Listening..."); 
      while (true) 
      { 
       //allDone.Reset(); 
       server.BeginAccept(new AsyncCallback(AcceptCon), server); 
       //allDone.WaitOne(); 
      } 
     } 

     void AcceptCon(IAsyncResult iar) 
     { 
      Socket oldserver = (Socket)iar.AsyncState; 
      Socket client = oldserver.EndAccept(iar); 
      Console.WriteLine(client.RemoteEndPoint.ToString() + " connected"); 
      byte[] message = Encoding.ASCII.GetBytes("Welcome"); 
      client.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(SendData), client); 
     } 

     void SendData(IAsyncResult iar) 
     { 
      Socket client = (Socket)iar.AsyncState; 
      int sent = client.EndSend(iar); 
      client.BeginReceive(data, 0, size, SocketFlags.None, new AsyncCallback(ReceiveData), client); 
     } 

     void ReceiveData(IAsyncResult iar) 
     { 
      Socket client = (Socket)iar.AsyncState; 
      int recv = client.EndReceive(iar); 
      if (recv == 0) 
      { 
       client.Close(); 
       server.BeginAccept(new AsyncCallback(AcceptCon), server); 
       return; 
      } 
      string receivedData = Encoding.ASCII.GetString(data, 0, recv); 
      //process received data here 
      byte[] message2 = Encoding.ASCII.GetBytes("reply"); 
      client.BeginSend(message2, 0, message2.Length, SocketFlags.None, new AsyncCallback(SendData), client); 
     } 
    } 

回答