2009-01-26 5 views
11

Ich verwende C# .Net und die Socket-Klasse aus dem Namespace System.Net.Sockets. Ich verwende die asynchronen Empfangsverfahren. Ich verstehe, dass dies leichter mit etwas wie einem Web-Service getan werden kann; Diese Frage ergibt sich eher aus meiner Neugier als aus praktischer Notwendigkeit.C# stream hat alle Daten empfangen?

Meine Frage ist: Angenommen, der Client sendet ein binär-serialisiertes Objekt unbekannter Länge. Wie kann ich auf meinem Server mit dem Socket wissen, dass das gesamte Objekt empfangen wurde und für die Deserialisierung bereit ist? Ich habe überlegt, das Objekt mit der Länge des Objekts in Bytes voranzustellen, aber das scheint in der .NET-Welt unnötig. Was passiert, wenn das Objekt größer als der Puffer ist? Wie sollte ich wissen, 'hey, muss die Größe des Puffers ändern, weil das Objekt zu groß ist'?

Antwort

11

Sie entweder das Protokoll müssen selbstabschließend sein (wie XML ist, effektiv - Sie wissen, wenn Sie ein XML-Dokument abgeschlossen haben empfangen, wenn sie das Element root schließt) oder müssen Sie Länge-Präfix die Daten, oder Sie brauchen das andere Ende, um den Stream zu schließen, wenn es fertig ist.

Im Falle eines selbst abgeschlossenen Protokolls müssen Sie genügend Haken haben, damit der Lesecode erkennen kann, wann es fertig ist. Bei der binären Serialisierung können Sie nicht genug Haken haben. Längen-Präfix ist hier bei weitem die einfachste Lösung.

4

Wenn Sie reine Sockets verwenden, müssen Sie die Länge kennen. Andernfalls ist die Größe des Puffers nicht relevant, denn auch wenn Sie einen Puffer der Größe der gesamten Daten haben, kann es immer noch nicht alles einlesen - überprüfen Sie die Stream.Read-Methode, es gibt die Anzahl der tatsächlich gelesenen Bits zurück, Sie müssen also eine Schleife machen, bis alle Daten empfangen sind.

0

Ja, Sie werden nicht deserialisieren, bis Sie alle Bytes rxed haben.