2011-03-13 10 views
2

J'ai écrit la majeure partie du code pour gérer les paquets entrants pour mon serveur. Le format des paquets est toujours int/int/int/string/string, et le premier int est la taille du paquet. Je dois trouver un moyen de vérifier et de voir si le paquet entier est arrivé ou si j'ai besoin d'attendre plus de pièces à venir, mais avec la façon dont j'ai écrit mon code, je ne peux pas penser à un bon moyen. Toute aide serait super car mon cerveau est probablement en train de trop réfléchir.Lecture des paquets TCP divisés

private void ReadClientPacket(object client) 
{ 
    TcpClient tcpClient = (TcpClient)client; 
    NetworkStream clientStream = tcpClient.GetStream(); 

    while (true) 
    { 
     try 
     { 
      int packetsize; 

      // Create a new Packet Object and fill out the data from the incoming TCP Packets 
      RCONPacket packet = new RCONPacket(); 

      using (BinaryReader reader = new BinaryReader(clientStream)) 
      { 
       // First Int32 is Packet Size 
       packetsize = reader.ReadInt32(); 

       packet.RequestId = reader.ReadInt32(); 
       packet.ServerDataSent = (RCONPacket.SERVERDATA_sent)reader.ReadInt32(); 

       Console.WriteLine("Packet Size: {0} RequestID: {1} ServerData: {2}", packetsize, packet.RequestId, packet.ServerDataSent); 

       // Read first and second String in the Packet (UTF8 Null Terminated) 
       packet.String1 = ReadBytesString(reader); 
       packet.String2 = ReadBytesString(reader); 

       Console.WriteLine("String1: {0} String2: {1}", packet.String1, packet.String2); 
      } 

      switch (packet.ServerDataSent) 
      { 
       case RCONPacket.SERVERDATA_sent.SERVERDATA_AUTH: 
       { 
        ReplyAuthRequest(packet.RequestId, clientStream); 
        break; 
       } 
       case RCONPacket.SERVERDATA_sent.SERVERDATA_EXECCOMMAND: 
       { 
        ReplyExecCommand(); 
        break; 
       } 
       default: 
       { 
        break; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
      break; 
     } 
    } 

    tcpClient.Close(); 
} 

Répondre

1

Ce que vous avez devrait fonctionner, car le flux sous-jacent attendra plus de données. Autrement dit, si vous appelez le clientStream.ReadByte et qu'il n'y a pas d'octets disponibles, la méthode bloquera jusqu'à ce que les données arrivent ou jusqu'à ce que le flux soit fermé - dans ce cas, probablement déconnecté par le serveur.

BinaryReader jusqu'à ce qu'il y ait suffisamment de données pour satisfaire la demande de lecture, donc le code devrait fonctionner comme prévu.

+0

Merci beaucoup! –