[Vienna-pm] vermeiden von deadlocks bei tcp-communikation/ übertragen von beliebigen strings

Bernd Petrovitsch bernd at firmix.at
Thu May 18 01:51:32 PDT 2006


On Wed, 2006-05-17 at 12:30 +0200, peter pilsl wrote:
> Ich hab ein sehr einfaches szenario:
> 
> ein client sendet einen string an den server und der server schickt dann 
> einen antwortstring zurück und der client terminiert.
> 
> 
> Das Problem ist, dass der string selbst ein serialized (module Storable) 
> hash (mit vielen unter- unter- hashes ist) und daher eigentlich jedes 
> zeichen enthalten kann.
> 
> Wie weiss nun der Server, wenn der Client mit dem Senden seines Strings 
> fertig ist?
> 
> Ich hab jetzt ein paar Lösungen selbstgestrickt, die auch funktionieren, 
> die mich aber alle nicht wircklich überzeugen:
> 
> * der client sendet zuerst die länge des strings, damit der server weiss 
> wieviele bytes er lesen muss
> * der client sendet einen ganz komplexen string-ende-string ala 
> \0\n\0\0\0\0\n und der programmierer betet, dass dieser string nie im 
                                       ^^^^^
> übertragenen string vorkommt und setzt $/ entsprechend:)

Na dann wundert sich hoffentlich niemand, wo soviel buggy Software
herkommt, wenn man solche broken-by-design-Lösungen überhaupt seriös
(abgesehen von abschreckenden Beispielen) ins Auge faßt.

> ich habe einfach das gefühl, dass es in der praxis fälle geben wird, die 
> diese lösungen aushebeln werden. (stringlänge und utf8 schreit schon 
> wieder nach ärger, wenn client und server auf unterschiedlichen systemen 
> laufen usw.)

Dann sollte der rationale Verstand über das Gefühl herrschen: Sobald du
die Länge (in Bytes!) voranstellst, ist ja wohl eindeutig klar, wieviele
Bytes da rüberkommen.
Wenn der Sender 5 mehr schickt, ist er kaputt ().
Den Ärger hast du eine Eben höher: Beide Seiten müssen das Array of Byte
interpretieren können. Wenn die sich (bei Texten) schon über das
Charset/Encoding nicht einig sind, wird das die untere
"übertrage-n-Byte" Funktionen nicht beheben können.

> Wie macht man das vernünftig/einfach/verlässlich?
> 
> Soll man den string encoden?

Ist das ein Fangfrage? Es gibt keine anderen Strings.

> Kann man ein meta-EOF schicken?

Willst du Byte-Stuffing implementieren?

> Wie machen das die anderen?

Hängt da von ab - siehe z.B. W. Laun's Email.
Bei ganz obigem Problem: Du serialisierst den String. Dann weiß du, wie
lange er ist. Dann schickst du die Länge (Hack alert: nicht binär,
sonder textuell mit einem ' ' oder \n als Ende - dann ist das Protokoll
HW-unabhängig) und dann den fertigen String als Blob.

> wie ist das mit dem datei-EOF eigentlich? Da funktioniert das alles ganz 
> einfach. Man setzt $/ auf undef und schlürft alles in einem rein? Das 
> fkt. bei meinem Server/Client-Modell nicht.

Sicher geht das: EOF ist, wenn der Sender "close()" (oder "shutdown()")
aufruft (z.B. macht das ftp bei den Data Connections so). Willst du das?

> Bisher hatte ich nur mit Server/Client-modellen zu tun, wo ein 0x10 ein 
> echter zeilenumbruch war und das ende einer eingabe markiert hat.

Naja, wenn du Zeichen definieren kannst, die garantiert nie in der
Payload vorkommen (und dieses auch durchhälst), kann man ohne
Byte-Stuffing ein "Meta-EOF" u.a. Signalisierung machen.

	Bernd
-- 
Firmix Software GmbH                   http://www.firmix.at/
mobil: +43 664 4416156                 fax: +43 1 7890849-55
          Embedded Linux Development and Services



More information about the Vienna-pm mailing list