2017-01-23 4 views
0

Comment puis-je arrêter d'envoyer un message à un client, alors que le client ne lit pas un message du serveur. Pour mieux comprendre ce que cela signifie, considérez un scénario dans lequel un client n'appelle pas Read pendant une période de temps prolongée et le serveur arrête d'envoyer un message à ce client. Server.cs recevoir des messages du client, et d'envoyer à tous les clientsSocket plusieurs client un serveur

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

Répondre

0

Le problème est que lorsqu'un client ne lit pas le tampon, le receivebuffer du client sera plein et le serveur bloquera dans l'exécution. Vous pouvez empêcher cela par:

  • Mettre en file d'attente les données pour chaque client. Le client doit demander des données, de sorte que le serveur envoie sa file d'attente. (sur un thread différent)
  • Utilisez le socket.Blocking = false sur le socket sur le serveur. Lorsque le serveur envoie les données et que les tampons sont pleins, vous obtenez une exception WouldBlock ou lorsque vous utilisez la surcharge appropriée lors de l'envoi, un SocketErrorCode est renvoyé. Windows Sockets: Blocking. Vous avez toujours besoin d'une file d'attente.

Le SendData pourrait être fait en parallèle, parce que le ByteBuffer/données ne change pas lors de l'envoi.