Autor Beitrag
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 27.01.06 12:01 
Datenpakete bei den Socket-Komponenten auseinanderhaltenMeta: Sockets Paket Pakete Packet Packets trennen auseinanderhalten zusammen Daten IP TCP TCP/IP Socket Client Server Kommunikation

Auszug aus dem Terminatorzeichen-Protokoll-Tutorial, Teil 1, Kapitel 3.2

Der Punkt mit den Datenpaketen ist für Anfänger in Sachen Netzwerk häufig etwas unverständlich. Das liegt daran, dass die Komponenten TClient- und TServerSocket (standardmäßig) mit asynchronen Ereignissen arbeiten, die - bei geringer Datenrate - den (Trug-)Schluss nahe legen, dass es ein Signalisierungsverfahren gibt. Was ist denn das schon wieder? Bisher arbeitet unser Chat ungefähr so:

  • Der Chat-Teilnehmer gibt eine Nachricht ein und klickt auf den Senden-Button.
  • Der Text wird per .SendText() an den Server geschickt.
  • Dort wird das Ereignis OnClientRead ausgelöst.
  • Der Text wird per .ReceiveText gelesen und weiterverarbeitet.

Der Schluss liegt nahe, dass zu jedem gesendeten Text ein passendes Ereignis im Empfänger ausgelöst wird, so dass .ReceiveText genau das liefert, was .SendText() auf den Weg gebracht hat. Offensichtlich klappt das auch, denn unser Chat-System arbeitet ja korrekt. Leider funktioniert das aber nur deshalb, weil die Datenrate (die Menge der gesendeten Daten pro Zeiteinheit) klein genug ist, um das Ereignissystem von Windows nicht zu überfordern (das nicht sehr schnell ist). Würden sehr viel mehr Daten auf einmal gesendet, könnten in der Zeit, bis die Ereignisverarbeitung in unserem Programm beginnt, bereits weitere Daten eingetroffen sein! Dann würde .ReceiveText mehr liefern, als von den einzelnen .SendText()-Aufrufen gesendet wurde. Zur Veranschaulichung hier eine Darstellung des zeitlichen Ablaufs:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  |                               |     |
+-|-------------------------------|-----|-------\
| Hallo, das ist ein langes Wort  |     Test     > Sender
+-|---------------------g---------|-----|-------/   |
  |                    n          |     |           |
+-|-------------------a-----------|-----|-------\   v
| Hallo, das ist ein langes Wort  |     Test     > Empfänger
+-|-------------------------------|-----|-------/
  |                               |     |
--|-------------------------------|-----|--------> Zeitachse
  |                               |     |
 (A).............................(B)   (C)

(A) Sender führt aus: Socket.SendText('Hallo, das ist ein langes Wort'); Das erste Zeichen kommt im Empfangspuffer an, daraufhin wird eine Windowsnachricht von der WSA an unser Programm gesendet.

(B) Die Windows-Nachricht trifft in unserem Programm ein und es wird das Ereignis OnClientRead ausgelöst. Ein folgender Aufruf von .ReceiveText liefert genau den gesendeten Text, zufällig!

(C) Der nächste Text wird gesendet.

(A) bis (B): Zeit, bis die WSA-Nachricht vom Betriebssystem verarbeitet wurde

Würden wir im Beispiel "Test" nahtlos senden, dann würde .ReceiveText beide Strings liefern und auch kein weiteres Ereignis eintreten. Damit sollte klar sein, dass es nicht möglich ist (oder zumindest nicht zweifelsfrei!), aus den Ereignissen Rückschlüsse auf die gesendete Datenmenge zu ziehen. Ist die Datenrate ausreichend hoch, wird nicht zu jedem Sendevorgang ein zugehöriges Empfangsereignis ausgelöst.

Als Konsequenz daraus ergibt sich die Tatsache, dass der Server die Daten als kontinuierlichen Strom von Zeichen sieht, und nicht als Folge von gesendeten Nachrichten mit zugehörigem Empfangsereignis. Deshalb müssen wir selbst dafür sorgen, dass Datenpakete (genauer gesagt, deren Grenzen) deutlich werden.

Im Tutorial wird im weiteren Verlauf gezeigt, wie man das Problem lösen kann.

Moderiert von user profile iconjasocul: Beitrag geprüft am 08.06.2006

_________________
There are 10 types of people - those who understand binary and those who don´t.