2010-04-25 2 views
3

Я работаю над клиент-серверным приложением на C#, и мне нужно заставить работать асинхронные сокеты, чтобы я мог обрабатывать сразу несколько соединений. Технически это работает так, как сейчас, но я получаю OutOfMemoryException примерно через 3 минуты работы. MSDN говорит, чтобы использовать WaitHandler, чтобы сделать WaitOne() после socket.BeginAccept(), но это на самом деле не позволяет мне это делать. Когда я пытаюсь сделать это в коде, он говорит, что WaitHandler - абстрактный класс или интерфейс, и я не могу его создать. Я подумал, что, возможно, Id попробует статическую ссылку, но у нее нет метода WaitOne(), только WaitAll() и WaitAny(). Основная проблема заключается в том, что в документах он не дает полного фрагмента кода, поэтому вы не можете увидеть, что происходит с их обработчиком ожидания. его просто переменная, называемая allDone, которая также имеет метод Reset() в фрагменте, которого нет у waithandler.C# Asynchronous Network IO и OutOfMemoryException

После того, как в своих документах выкопались, я нашел связанную вещь о AutoResetEvent в пространстве имен Threading. Он имеет 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); 
     } 
    } 

ответ