2017-01-23 5 views
0

Как я могу прекратить отправку сообщения клиенту, в то время как клиент не читает сообщение с сервера. Чтобы лучше понять, что это значит, рассмотрите сценарий, в котором клиент не вызывает Read в течение длительного периода времени, и сервер перестает отправлять сообщение этому клиенту. Server.cs получить сообщение от клиента, и отправить всем клиентамSocket multiple client one server

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 на сокете на сервере. Когда сервер отправляет данные, а буферы заполняются, вы получите исключение WеBlock или при правильной перегрузке при отправке возвращается SocketErrorCode. Windows Sockets: Blocking. Вам все еще нужна очередь.

The SendData можно сделать параллельно, потому что ByteBuffer/данные не изменяется во время отправки.