Wenn ja, wie würde der Empfang aussehen, wenn man auf ein bestimmtes Line-Ending wartet?
Dazu haben QuickAndDirty und Mavarik oben schon etwas gesagt.
Stell dir ein Buch vor:
Du gehst Zeile für Zeile durch und erkennst an der Positionierung und Formatierung, wann du eine Seitenzahl und wann ein neues Kapitel vor dir hast. Aber du liest das Buch dabei einfach von vorne bis hinten, ohne dass du auf bestimmte Kennzeichen wartest.
Und genauso geht man auch bei einer solchen Übertragung vor. Stell dir ein ganz einfaches Protokoll vor: # ist der Start einer Überschrift, $ der Start einer Seitenzahl, am, - startet einen Text und Ende kommt immer ein *.
Beispiel:
$1*#Überschrift*-Das ist ein Text.$2*-Und noch mehr Text!**$44*#Überschrift*-Das ist ein kleiner Text.$45*-Und noch ein wenig Text!**
Nun bekommst du:
$1*#Überschrift*-Das ist e
Dann gehst du zeichenweise durch und fügst die Zeichen einzeln zu deinem Empfangspuffer (sprich eine Stringvariable) hinzu. Findest du ein doppeltes **, also dein Paketende, gibst du deinen Empfangspuffer als vollständiges Paket weiter und leerst ihn. Das machst du einfach immer so weiter, wenn du etwas empfängst. In diesem Fall wäre das Paket nicht vollständig, also wartest du weiter, bis du den nächsten Teil empfängst.
Pseudocode in etwa:
Code:
Buffer := '';
while Connection.Active do
begin
if Connection.HasData then
begin
Data := Connection.GetData;
FoundEndChar := False;
for i := 1 do Length(Data) do
begin
Buffer := Buffer + Data[i];
if Data[i] = EndeZeichen then
if FoundEndChar then // das letzte Zeichen war schon ein EndeZeichen --> doppeltes Ende gefunden
begin
VerarbeitePaket(Buffer);
Buffer := '';
FoundEndChar := False;
end
else
FoundEndChar := True // ein erstes EndeZeichen
else
FoundEndChar := False; // egal ob vorher ein einzelnes war oder nicht, aktuell kein EndeZeichen
end;
end
else
Sleep(1); // kurz warten, damit die Schleife nicht so viel Leistung zieht
end;
Und zur Analyse: Du gehst durch...
$ --> Seitenzahl, also fängt ein Paket an.
1 --> Aktueller Status ist Seitenzahl
* --> Aktueller Status ist Seitenzahl, die ist damit vollständig --> Seite "2"
# --> Überschrift beginnt
Ü...t --> Überschriftsinhalt
* --> Überschrift beendet --> "Überschrift"
- --> Text beginnt
D..e --> weiterer Text
An der Stelle weißt du, dass das Paket noch nicht vollständig ist. Also wartest du auf den nächsten Teil, packst den hinten dran und prüfst erneut.
Und so gehst du einfach zeichenweise durch, merkst dir, wo du bist, prüfst, ob der nächste Inhalt so im Zusammenhang passt, ...
Am Ende bist du dann am ersten Sternchen, bist im Modus "im Paket" und bekommst das zweite Sternchen. Damit ist das Paket vollständig und du kannst es zur Bearbeitung weitergeben.
Das ist eine Möglichkeit. Das Prinzip nennt sich
endlicher Automat. Du kannst die schon vorhandenen Teile des Pakets dabei direkt in einer Struktur ablegen und aus deinem Empfangsstring entfernen oder du machst das erst, wenn du das Ende hast.
Du kannst aber auch wie oben schon angesprochen wurde, die Länge direkt am Anfang mitschicken. Dann weißt du, wie viele Bytes danach kommen. Du kannst z.B. eine Überschrift so aussehen lassen:
PAKET54*#11*Überschrift*
PAKET --> neues Paket
5..4 --> Paketlänge
* --> Paket ist 54 Bytes lang
# --> Überschrift Start
1..1 --> Länge
* --> Überschrift ist 11 Bytes lang
...
Es gibt wirklich viele Möglichkeiten und das ist nur ein ganz kurzer Einstieg, damit du eine grundsätzliche Idee hast, wie du mit Datenströmen arbeiten kannst. Es gibt natürlich andere und sicher auch schönere Lösungen.
Die ganz simple Variante wäre, mit Pos in dem String nach dem Endezeichen zu suchen.