PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [.NET] Networkstream.Read synchronisation - 2 Fragen


Kennung Eins
2007-02-12, 11:20:12
1.)
Angenommen ich habe einen Server, der mir "AAAAAAAAAA" schickt. Wenn ich jetzt in meinem Client mittels NetworkStream.Read die Daten einlese, kommt dann garantiert immer "AAAAAAAAAA" beim Client an, oder kann es auch passieren, dass nur irgend ein Teil der Nachricht ankommt?

2.)
Jetzt das ganze noch ein bisschen konkretisiert:
Wird garantiert, dass in dem Moment, wo ich NetworkStream.Read ausführe, auch wirklich schon alle Bytes vom Client beim Server angekommen sind?

Beispiel: schlechte WLAN-Verbindung
- Der Server schickt "AAAAAAAAAA".
- Der Client registriert, dass Daten am Socket anliegen und fängt an zu lesen.
- Da das Netz echt beschissen ist, ist bisher beim Client nur "AAAA" angekommen.
- Der Client hört bei "AAAA" auf zu lesen, da bei ihm nicht mehr anliegt.
- Die restlichen Bytes sind dann wohl verloren

Können die oben genannten Fälle eintreten?

Ich stelle die Frage deswegen, weil ich bisher davon ausgegangen bin, dass .NET solcherlei Funktionalitäten schon mitbringt, dass sich also der Programmierer um diesen Datenverlust nicht kümmern muss. Doch inzwischen bin ich mir da nicht mehr sicher.

Gnafoo
2007-02-12, 11:36:02
Hm ich würde sagen, wenn du TCP als Protokoll für den zugrundeliegenden Socket benutzt, bist du generell aus dem Schneider. Das sichert eigentlich von sich aus, dass alles ankommt.
http://de.wikipedia.org/wiki/Transmission_Control_Protocol#Datenintegrit.C3.A4t_und_Zuverl.C3.A4ssigkeit

Kennung Eins
2007-02-12, 12:59:45
Ok, angenommen es kommt "irgendwann" alles an, kann trotzdem Fall 2 eintreffen?

[edit]
In dem Wikipedia-Link steht:
Der Sender wiederholt das Senden von Paketen, falls keine Bestätigung innerhalb einer bestimmten Zeitspanne (Timeout) eintrifft.
Muss ich mich um das Wiederholen der Sendung kümmern, oder geschieht das automatisch?

BavariaBlade
2007-02-12, 14:48:05
Nein, soweit ich weiß macht das alles TCP für dich.
Bei UDP musst du da aber acht geben :"Fire and Forget", funkioniert ähnlich wie bei Radiosendern (Broadcasting) ohne Kontrolle was, wann, wo ankommt.

Gnafoo
2007-02-12, 14:49:49
Die Checksumme sichert ab, dass zumindest ein Paket immer als Ganzes und mit dem richtigen Inhalt ankommt. Wenn das Schreiben in den Stream also nur ein Paket produziert, dürfte dein Fall 2 nicht auftreten. Sind es mehrere Pakete und eines kommt nicht an, dann wird der Sender (automatisch) das Paket mehrmals schicken, bis es ankommt. Bekommt er in absehbarer Zeit keine Bestätigung vom Empfänger, dann gibt es einen Timeout und die Verbindung wird getrennt.

Das Wiederholen, Prüfen der Checksumme, etc. pp. geschieht bereits automatisch durch das Betriebsystem.

Allerdings alles ohne Gewähr und "soweit ich weiß". Wäre von daher nicht schlecht, wenn das noch jemand anderes bestätigen könnte.

Unfug
2007-02-12, 14:57:44
99% richtig.

Nicht das Betriebsystem überprüft sondern das Protokoll. In diesem Fall TCP/IP.
Ohne groß in die Materie einzugehen:
TCP ist ein Protkoll was Dir garantiert, daß alle Daten ankommen, ausser natürlich Du machst den PC aus oder deine WLAN Verbindung bricht ganz ab.

Somit wirst Du keine Probleme damit haben.

Gruß

Kennung Eins
2007-02-12, 15:05:13
Ok .. ich danke euch.

Gast
2007-02-13, 14:12:46
Ok, angenommen es kommt "irgendwann" alles an, kann trotzdem Fall 2 eintreffen?


Es ist aber nicht garantiert, dass du alle Daten mit "einen" Read bekommst. Gründe wären z.B., dass der Puffer zu klein ist oder die Verbindung zu langsam. Folgendes Bsp. ist aus der MDSN kopiert:

// Check to see if this NetworkStream is readable.
if(myNetworkStream.CanRead){
byte[] myReadBuffer = new byte[1024];
StringBuilder myCompleteMessage = new StringBuilder();
int numberOfBytesRead = 0;

// Incoming message may be larger than the buffer size.
do{
numberOfBytesRead = myNetworkStream.Read(myReadBuffer, 0, myReadBuffer.Length);

myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));

}
while(myNetworkStream.DataAvailable);

// Print out the received message to the console.
Console.WriteLine("You received the following message : " +
myCompleteMessage);
}
else{
Console.WriteLine("Sorry. You cannot read from this NetworkStream.");
}