2016-10-27 6 views
0

Ich versuche, die Anzahl der Bytes zu ermitteln, die zum Lesen verfügbar sind, so dass ich von der SslStream lesen kann, bis alle Daten gelesen wurden. SslStream scheint keine Eigenschaft oder Methode dafür zu haben, also habe ich versucht, die zugrunde liegende Socket zu verwenden. Das Problem hier ist, dass die Anzahl der verfügbaren Bytes, wie von der Socket gemeldet, nicht mit der tatsächlichen Menge der entschlüsselten Daten, die ich brauche, übereinstimmt.Kann die Anzahl der verfügbaren Bytes für SslStream nicht bekommen

Hier ist meine Methode Receive:

byte[] Receive() 
{ 
    byte[] messageBuffer = new byte[4096]; 
    int bytesRead = 0; 

    using (var readData = new MemoryStream()) 
    { 
     while(Client.Client.Available > 0) 
     { 
      bytesRead = Stream.Read(messageBuffer, 0, messageBuffer.Length); 
      readData.Write(messageBuffer, 0, bytesRead); 
     } 

     return readData.ToArray(); 
    } 
} 

Client.Client ist die zugrunde liegende Socket von Stream, die die SslStream ist. Nehmen wir eine Nachrichtengröße von 5000 Bytes an. Es gibt ein paar Probleme hier:

  1. Der erste Versuch Client.Client.Available kehrt 5077. Dies ist nicht die richtige Länge der zu lesende Daten vorhanden.
  2. Nach dem ersten Anruf an Stream.Read Client.Client.Available gibt 0 zurück, also verlasse ich die Schleife, obwohl ich nur 4096 gelesen habe, da das meine Puffergröße ist. Es verbleiben also 904 Bytes im Stream, die nicht gelesen wurden.

So scheint es, dass, nachdem ich Stream.Read nenne es die gesamten Daten aus dem Sockel entfernt (alle 5000 Bytes nicht nur die 4096 für frage mich), was Sinn macht, weil Sie die gesamte Nachricht brauchen es zu entschlüsseln. Aber es gibt keine Möglichkeit zu wissen, ob Sie die gesamte Nachricht erhalten haben, denn es gibt keine SslStream.Available oder etwas Ähnliches. Meine Frage ist also, wie kann ich feststellen, ob ich die gesamte entschlüsselte Nachricht erhalten habe? (Oder wie kann ich die Anzahl der Bytes der entschlüsselte Nachricht?)

Andere Dinge, die ich versucht habe:

  • mit Client.Client.Poll(someLongTimeoutForTesting, SelectMode.SelectRead) aber es gibt false zurück, nach dem ersten Stream.Read auch.
  • mit Client.GetStream().DataAvailable wieder false zurück, nachdem die ersten Stream.Read
  • die Größe des Message auf den maximalen Betrag zu erhöhen Stream.Read zurückkehren (16299, nicht sicher, warum diese Zahl aber wenn ich erhöhe die Nachrichtengröße und Puffergröße über diesem Stream.Read() gibt immer 16299 zurück). Diese Methode funktioniert, aber es verwendet eine unangemessene Menge an Speicher, da in der Anwendung in den Client Nachrichten unter 4096 99,99% der Zeit verwendet werden.

Antwort

0

Wenn Sie Nachrichtenlänge kennen, können Sie Bytes Array gelesen und dann von diesem Array erstellen stream:

buffer = new byte[num_of_bytes]; 
    for (int i = 0; i < num_of_bytes; i++) 
     buffer[i] = (byte)sslStream.ReadByte(); 

    using (var stream = new MemoryStream(buffer)) 
    {     
    } 
+0

Ich weiß nicht die Länge der Nachricht, das ist genau das, was ich versuche zu bestimmen.Ich habe 5000 in meinem Beispiel verwendet, um mein Problem zu demonstrieren – CSCoder

0

Wenn Sie mit TCP-Sockets (Streams) arbeiten Sie benötigen, um Ihre eigene Anwendung zu implementieren Schichtprotokoll. Eine sehr einfache Lösung: Sie geben die Nachrichtengröße in den ersten beiden Bytes an (z. B. könnte es die von Ihnen gewählte Länge sein), Sie können auch ein oder zwei Bytes für den Nachrichtentyp zuweisen, der Rest ist die Payload. Sie wissen also, dass immer die ersten zwei Bytes die Länge angeben, also müssen Sie 2 Bytes lesen. Dann bekommst du die Payload-Länge. In diesem Moment weißt du wie viele Bytes du lesen kannst. Ich erkläre es mit mehr Details, nicht für SslStream, aber die Antwort gilt auch für Ihren Fall, hier: How to read all of Inputstream in Server Socket JAVA

+0

Danke für die Antwort! Dies wäre eine gute Lösung, leider ist dies für mich keine Option, da ich den Client-Code nicht aktualisieren kann. Ich kann validieren, dass die Nachricht, die ich empfange, dem erwarteten Format entspricht, also bin ich mit dem Empfang von schlechten/unvollständigen Nachrichten manchmal in Ordnung, aber mein Problem ist, dass wenn die Nachricht die messageBuffer Größe überschreitet, ich nie die richtige/vollständige Nachricht bekomme. – CSCoder

Verwandte Themen