2009-05-08 9 views
1

Ich habe dieses Stück Code, der eine Reihe von Nachrichten empfängt:Sockel nur ein Teil der Nachricht C# Empfang

byte[] buffer = new byte[10240]; 
//... 
sock.Receive(buffer); 
string response = message(buffer); 
Console.WriteLine("Message Recieved"); 
if (!verifyUser(response, sock)) 
Console.WriteLine("User Invalid"); 
//... 
static private bool verifyUser(string userString, Socket sock) 
{ 
    string[] userData = userString.Split(' '); 
    int i = 0; 
    while (true) 
    { 
     if (userData[0].ToUpper() != "USER") 
     { 
      byte[] buffer = message("WHO"); 
      sock.Send(buffer); 
      userData = userString.Split(' '); 
      i++; 
      if (i > 4) 
      { 
         return false; 
        } 
        continue; 
       } 
       else 
        break; 
      } 
Console.WriteLine("Connection recieved from " + userData[1] + " with hash of "/* + userData[2]*/); 
} 

Das Problem, das ich habe, ist, dass, wenn ich den Benutzernamen Unkwntech alle tragen vor, dass es angezeigt wird unkwnt, und der zweite Wert scheint nie da zu sein. der App, die das Senden von Daten wie folgt aussieht:

static void Main(string[] args) 
     { 
      Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); 
      EndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 200); 
      sock.Connect(remoteEP); 
      byte[] buffer = Encoding.ASCII.GetBytes("USER unkwntech a3f5h4a35sfg");//Made up hash 
      sock.Send(buffer); 
      sock.Receive(buffer); 
      Console.WriteLine(Encoding.ASCII.GetString(buffer)); 
      Console.ReadLine(); 
     } 
+0

Können Sie die Definition der "Nachrichten" -Funktion anzeigen? Haben Sie die Anwendung getestet? Wann sind Daten verloren? –

Antwort

7

Sie sind vorausgesetzt, dass, wenn Sie senden, werden alle Daten endet in einem einzelnen Paket auf, und dass Sie in einem Rutsch alle Daten werden erhalten am anderen Ende. So funktioniert TCP/IP nicht. Es ist ein Streaming-Protokoll - Sie sollten niemals Annahmen darüber treffen, wie viele Daten Sie gleichzeitig erhalten.

Grundsätzlich müssen Sie aus dem Stream lesen, bis Sie entweder alle Daten gelesen haben und der Socket geschlossen wurde, oder bis Sie "genügend" Daten haben. Wenn Sie die Kontrolle über das Protokoll haben und es sich um ein Konversationsprotokoll handelt, wird das Leben viel einfacher, wenn jeder Nachricht, die Sie senden, die Länge vorangestellt wird - dies bedeutet, dass das andere Ende weiß, wie viele Daten zu erwarten sind.

1

Überprüfen Sie den Rückgabewert Ihres Socket.Receive-Aufrufs. Es gibt die Anzahl der empfangenen Bytes zurück. Sie können diesen Aufruf in eine Schleife einfügen und lesen, bis Sie die Anzahl der erwarteten Bytes erhalten haben. Sie sollten sich auch vor Endlosschleifen schützen, indem Sie eine maximale Anzahl von Versuchen festlegen oder, wie John vorgeschlagen hat, den Status des Sockets überprüfen. Nehmen Sie außerdem nicht an, dass ein Rückgabewert von Null bedeutet, dass Sie die gesamte Nachricht gelesen haben.

Wenn Ihr Protokoll jede Nachricht mit der vorangestellten Länge hat, sollte Ihr Protokoll auch ein Markierungsbyte definieren, um das Ende des Headers mit vorangestellter Länge zu markieren, um wirklich kugelsicher zu sein. Lesen Sie ein Byte nach dem anderen, bis Sie das Marker-Byte sehen. Berechnen Sie dann die Länge der Nachricht und lesen Sie größere Teile ein, bis Sie alles gelesen haben.

Socket.Receive definiert eine Überladung, mit der Sie angeben können, wie viele Bytes Sie empfangen möchten. (Es ist jedoch nicht garantiert, dass Sie so viele empfangen, daher müssen Sie den Rückgabewert überprüfen.)

Verwandte Themen