2017-01-23 99 views
0

如何停止向客戶端發送消息,而客戶端不從服務器讀取消息。爲了更好地理解這意味着什麼,考慮一種情況,即客戶端在長時間內不會調用Read,並且服務器停止向該客戶端發送消息。 Server.cs從客戶端接收消息,發送給所有的客戶套接字多客戶端一臺服務器

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。當服務器發送數據並且緩衝區已滿時,您將收到一個DoesBlock異常,或者在發送時使用正確的過載時,將返回一個SocketErrorCode。 Windows Sockets: Blocking。你仍然需要一個隊列。

SendData可以並行完成,因爲字節緩衝區/數據不會在發送更改。

相關問題