2017-01-23 30 views
0

クライアントがサーバーからメッセージを読み取らないうちに、クライアントへのメッセージの送信を停止する方法を教えてください。これが何を意味するのかをよりよく理解するには、クライアントが長時間Readを呼び出さず、サーバーがこのクライアントにメッセージを送信しなくなるシナリオを考えてみましょう。 Server.csは、クライアントからメッセージを受信し、すべてのクライアントに送信ソケット複数クライアントの1つのサーバー

private static void ReceiveCallback(IAsyncResult AR) 
     { 
      Socket current = (Socket)AR.AsyncState; 
      int received; 
      try 
      { 
       received = current.EndReceive(AR); 
      } 
      catch (SocketException) 
      { 
       Console.WriteLine("Client forcefully disconnected"); 
       current.Close(); 
       clientSockets.Remove(current); 
       return; 
      } 
      byte[] recBuf = new byte[received]; 
      Array.Copy(buffer, recBuf, received); 
      string text = Encoding.ASCII.GetString(recBuf); 
      Console.WriteLine("Received Text: " + text); 
      buffQueue.Enqueue(text); 
      current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current); 
      foreach (var client in clientSockets) 
      { 
       foreach (var msg in buffQueue) 
       { 
        Sendata(client, text); 
       } 
       } 
      } 
     static void Sendata(Socket socket, string noidung) 
     { 
      byte[] data = Encoding.ASCII.GetBytes(noidung); 
      socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket); 

     } 
     private static void SendCallback(IAsyncResult AR) 
     { 
      Socket socket = (Socket)AR.AsyncState; 
      socket.EndSend(AR); 

     } 

Client.cs

public void ReceiveMessage(IAsyncResult ar) 
     { 
      Random rnd = new Random(); 
      Socket socket = (Socket)ar.AsyncState; 
      int received = socket.EndReceive(ar); 
      byte[] dataBuf = new byte[received]; 
      Array.Copy(receivedBuf, dataBuf, received); 
      string msg = Encoding.ASCII.GetString(dataBuf); 
      Console.WriteLine("> " + msg + '\n'); 
      ClientSocket.BeginReceive(receivedBuf, 0, receivedBuf.Length, SocketFlags.None, 
       new AsyncCallback(ReceiveMessage), ClientSocket); 
     } 

答えて

0

問題は、あるそのクライアントは、バッファ、クライアントのreceivebufferを読んでいないときサーバーがいっぱいになり、サーバーが実行をブロックします。

  • 各クライアントのデータをキューに入れます。クライアントはデータを要求しなければならないため、サーバーはキューを送信します。 (別のスレッド上)
  • サーバー上のソケットでsocket.Blocking = falseを使用してください。サーバーがデータを送信しているときにバッファがいっぱいになると、WouldBlock例外が発生するか、送信時に適切なオーバーロードを使用すると、SocketErrorCodeが返されます。 Windows Sockets: Blocking。依然としてキューが必要です。 ByteBuffer /データが送信中に変更されないため

SendData は、並列に行うことができます。

関連する問題