Hallo Leute,
da ich ein größeres Projekt plane, welches übers Netzwerk läuft habe ich
mir die posix Sockets angeschaut.
Ich brauche eine zuverlässige Verbinung, die Datagramme(einzele Pakete,
zb Strings) verschicken kann.
Da dort nur Streams zuverlässig funktioneren (jedenfalls habe ich nichts
dergleichen gefunden), habe ich die Funktionalität selbst eintwickelt
und das ganze hochtrabend "String Transmission Protocoll" genannt. ;-)
Hier ein kleiner Ausblick:
Im Anhang sind die Sourcen dafür, sowie zwei Testprogramme.
Einen kleine Fehler gibt es noch im Server Testprogramm:
Durch die Verwendung von pthreads wird Speicher allokiert, den ich nicht
freigeben kann(finde keinen pointer dafür :( ).
Ich bitte um Kommentare (Funktionalität, API, Programmierstil, etc.).
Viele Grüße
Stefan Beller
also die Vergrößerung des Buffers, hättest du auch billiger bekommen
können. Stichwort: realloc
realloc vergrößert den Buffer, falls das möglich ist. Wenn es dabei
ausnutzen kann, dass es im Speicher hinter dem Buffer brachliegenden
Speicher mitbenutzen kann, dann wird es das tun und sich so das
Umkopieren der Daten sparen. Andernfalls allokiert realloc neuen
Speicher und erledigt auch das Umkopieren.
1
switch(bytes_sent){
2
...
3
case-1:
4
/*an error occured, return 1 to indicate*/
5
return1;
6
break;
Hmm. Denkst du nicht, dass du zumindest versuchen solltest, den
Empfänger zu benachrichtigen?
Wenigstens soweit, dass du den Empfänger durch Übermittlung einer '\0'
aus seiner Warteschleife rauslässt.
Für eine Basis-Lib fehlt mir da die Abfrage von Fehlern. Du benutzt
malloc als ob du unendlich viel Speicher hättest. Für eine Lib-Funktion
ist das aber nicht akzeptabel. Der Returnwert von malloc muss abgefragt
werden und, viel spannender, man muss sich etwas überlegen wie es weiter
gehen soll, wenn man keinen Speicher mehr hat. Akzeptabel ist fast
alles, nur eines nicht: Das das Programm deswegen crasht bzw.
anderweitig Daten zerstört.
Aus diesen und ähnlichen Gründen wird daher bei Übertragungen gerne die
Länge des nun folgenden Datensatzes zuerst übertragen. Denn dann kann
sich der Empfänger einen entsprechend großen Buffer zurechtlegen. Die
Länge hat zwar den Nachteil, dass man einen Datentyp dafür vereinbaren
muss, auf der anderen Seite wiegt aber der Vorteil, dass der Empfänger
weiß was auf ihn zukommt, vieles auf.
Okay,
ich habe das Ganze ein wenig umgeschrieben.
Man muss zum Verbindungsaufbau nicht mehr angeben wie lang der längste
String ist, sondern am Anfang jeder Übertragung wird die Länge
übermittelt.
Das reallocate habe ich auch eingebaut.
(Dieses wird ohnehin nur im Fehlerfall aufgerufen.)
Alle malloc-Fehler werden auch abgefangen.
Nun den zweiten Punkt, den Karl Heinz ansprach, habe ich so umgebaut,
dass eine Fehlermeldung geworfen wird.
Gegenfrage: Wie teile ich dem Gegenüber mit, dass bei mir irgendetewas
nicht stimmt, wenn der Fehler darin besteht, das die send-Funktion nicht
ordnungsgemäß funktioniert?
Stefan B. schrieb:> Gegenfrage: Wie teile ich dem Gegenüber mit, dass bei mir irgendetewas> nicht stimmt, wenn der Fehler darin besteht, das die send-Funktion nicht> ordnungsgemäß funktioniert?
Das ist natürlich eine gute Frage und hängt auch davon ab, warum genau
eigentlich send das Versenden der Daten verweigert hat.
Jetzt fängt die Sache nämlich an komplizierter zu werden. Wie eigentlich
meistens wen Fehlerbehandlung ins Spiel kommt :-)
> Gegenfrage: Wie teile ich dem Gegenüber mit, dass bei mir irgendetewas> nicht stimmt, wenn der Fehler darin besteht, das die send-Funktion nicht> ordnungsgemäß funktioniert?
Z.B. indem du einen Watchdog nicht mehr triggerst.
Hallo,
so ich habe ein wenig an dem API herumgespielt.
send/recv sind threadsafe, dh. jeweils mit einem Mutex geschützt.
Das serverseitige stp_accept_connections läuft auch mit threads, sodass
diese Funktion nicht blockiert.
Damit ist dann zb so etwas möglich:
1
a=stp_accept_connections(port,&callback);
2
sleep(180);//warte 3 Minuten
3
stp_stop_accepting(a);//es werden keine neuen eingehenden Verbindungen akzeptiert.
Nun Fehlerbehandlung, wer mag sie nicht ? ;-)
Ich habe das soweit abstrahiert, dass man entweder senden/empfangen kann
oder nicht. Also der Systemzustand ist relativ binaer: funktioniert oder
funktioniert nicht.
Natürlich geht nichts in der Bibliothek derart schief, das das Programm
crashed, sondern es wird nur per Rückgabewert mitgeteilt, das die
Verbindung defekt ist.