2012-04-03 8 views
0

... im Grunde genau das, was der Titel sagt. NetworkStream.Length ist nicht implementiert. Was ist eine Alternative?Behelfslösung für .NET NetworkStream.Length Mangel an suppport

Ich versuche, eine rekursive Reihe von Asynchron-Rückrufe zu machen, die Anrufe zu NetworkStream.BeginRead (...) umhüllen. Um zu wissen, wann ich meinen Base Case getroffen und alle Bytes erhalten habe, muss ich die Länge der Bytes im Stream wissen. Gibt es einen Workaround dafür?

-Code (der Einstiegspunkt zu diesem Code nach TcpListern.BeginAcceptTcpClient Aufruf schreiben ist .:

private void StartRead(IAsyncResult ar) 
{ 
    try 
    { 
     //Do an initial read: 
     AsyncClient client = (AsyncClient)ar.AsyncState; 
     int amountRead = 0; 
     try 
     { 
     amountRead = client.ClientStream.EndRead(ar); 
     } 
     catch (IOException io) 
     { 
     ProcessDebugLog("Async read complete", io); 
     client.ClientStream.Close(); 
     return; 
     } 
     string text = Encoding.UTF8.GetString(client.Bytes, 0, amountRead); 

     //If TCP segmentation has occurred, more blocks will have 
     // to get read in: 
     if (client.ClientStream.Position < client.ClientStream.Length /*EXCEPTION HERE*/) 
     { 
     try 
     { 
      client.ClientStream.BeginRead(client.Bytes, 0, client.Bytes.Length, StartRead, client); 
     } 
     catch (IOException io) 
     { 
      ProcessDebugLog("Async read complete", io); 
      client.ClientStream.Close(); 
     } 
     } 
     else 
     { 
     client.ClientStream.Close(); 
     } 
    } 
    catch (Exception ex) 
    { 
     ProcessDebugLog("ERROR - StartRead", ex); 
    } 
} 
+1

kontrollieren Sie beiden Seiten der Verbindung? –

+2

Einige Streams sind wirklich Streams. Du weißt nicht, wie viel Wasser in diesem Fluss ist, bis das Wasser ausgeht. –

+0

@Boo Ja, ich kontrolliere beide Seiten. – kmarks2

Antwort

3

... im Grunde genau das, was der Titel sagt. NetworkStream.Length nicht implementiert. Was ist eine Alternative ?.

Sie halten bis zum Ende des Streams zu lesen Es ist keine Alternative dazu - bis der Strom geschlossen wurde, gibt es immer mehr Daten sein können

01.

Wenn Sie das Protokoll steuern, dann, wenn ein Strom kann mehr „Nachrichten“ enthalten sollten Sie längen Präfix jede Nachricht. (Sie können ein Trennzeichen als Alternative verwenden, aber das ist Messier.)

Beachten Sie, dass Sie sollten nicht dekodieren von binär in Text, bis Sie alle Daten haben, oder Sie sollten eine Decoder verwenden, das ist Sie können den Zustand von "unvollständigen" Zeichen beibehalten - für den Fall, dass Ihr Lesevorgang sich auf halbem Weg durch ein Zeichen aufteilt.

+0

Danke. Ich gehe die Delimiter-Route, da die Nachrichten in der Länge stark variieren können. Ich kontrolliere alle Kunden, damit ich das Chaos lindern kann. Ich arbeitete an einem FileStream-Beispiel, so dass mir nicht sofort auffiel, warum Länge ein Problem ist, aber Sie sind völlig richtig. Upvoted/gelöst. – kmarks2

+2

@ kmarks2: Warum sollten sie in ihrer Länge sehr unterschiedlich sein und einen Begrenzer vorschlagen? Wenn der sendende Code die Länge kennt, bevor er mit dem Senden dieser Nachricht beginnt, kann die Verwendung eines Längenpräfixes * viel * sauberer sein. –

+0

Implementierte Clients würden brechen. Auch sie enden alle identisch, was ich vernachlässigt habe. Wenn ich die Clients aktualisieren muss, kann es passieren, dass ich ein paar Fehler verursache. – kmarks2