2010-04-25 3 views
3

Je travaille sur une application client/serveur en C#, et j'ai besoin d'avoir des sockets asynchrones fonctionnelles pour pouvoir gérer plusieurs connexions à la fois. Techniquement, ça fonctionne comme ça maintenant, mais je reçois un OutOfMemoryException après environ 3 minutes de course. MSDN dit d'utiliser un WaitHandler pour faire WaitOne() après le socket.BeginAccept(), mais il ne me laisse pas faire cela. Lorsque j'essaie de faire cela dans le code, il est dit WaitHandler est une classe abstraite ou une interface, et je ne peux pas l'instancier. Je pensais que peut-être essayer une référence statique, mais il n'a pas la méthode WaitOne(), juste WaitAll() et WaitAny(). Le problème principal est que dans les docs il ne donne pas un extrait de code complet, donc vous ne pouvez pas réellement voir de quoi vient leur "wait handler". c'est juste une variable appelée allDone, qui a aussi une méthode Reset() dans l'extrait, ce qui n'est pas le cas d'un waithandler. Après avoir creusé dans leurs documents, j'ai trouvé quelque chose à propos d'un AutoResetEvent dans l'espace de noms Threading. Il a une WaitOne() et une méthode Reset(). J'ai donc essayé ça autour du while(true) { ... socket.BeginAccept(...); ... }. Malheureusement, cela ne prend qu'une seule connexion à la fois. Donc je ne sais pas vraiment où aller. Voici mon code:C# Asynchronous Network IO et OutOfMemoryException

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

Répondre