Socket-Verhalten
-
Oh man oh man, vielen Dank Leute.
Ihr habt mir sehr geholfen.
@Belli, da hast du recht. Das habe ich natürlich auch nicht bedacht.
//edit, aber das ändert doch nichts so wirklich, da ich ja sowieso nach einer gewissen menge aufhöre. sollte doch selbst so ohne probleme gehen?!@Cooky, ja der Rückgabewert wird geprüft. Habe ich schon programmiert. Ja, ich nutze schon select() um zu schauben, ob ich lesen kann.
@Pi, spricht was dagegen?
Vielen Dank Euch

-
-
314159265358979 schrieb:
zuckerlie schrieb:
@Pi, spricht was dagegen?
Spricht was dafür?

Übersicht?!
-
xDDDDDD
Spinner.
-
zuckerlie schrieb:
@Belli, da hast du recht. Das habe ich natürlich auch nicht bedacht.
//edit, aber das ändert doch nichts so wirklich, da ich ja sowieso nach einer gewissen menge aufhöre. sollte doch selbst so ohne probleme gehen?!Nein. Stell Dir vor, Du bist mit dem Lesen des Päckchens noch nicht ganz fertig. Sagen wir, Dir fehlen noch 3000 Byte. Nun sendet die Gegenstelle wieder 10000 Byte. Von Deinem Socket sind jetzt insgesamt 13000 Byte lesbar, wovon 3000 Byte noch zu dem aktuellen Päckchen gehören, und auch nicht mit den nächsten 10000 zusammengewürfelt werden dürfen.
Nun kommt Deinthis->iReturnPayload += ::recv(this->sock, recvbuf+this->iReturnPayload ,iPayload, 0);wobei iPayload ja die ganze Zeit den Wert 10000 hat.
Jetzt liest dieser Aufruf von recv möglicherweise mehr als die noch benötigten 3000 Byte, nämlich irgendwas zwischen 1 und 10000, weil Du 10000 (iPayload) als Maximalwert angegeben hast.
Alles klar?Zu allem Überfluss wird jetzt nicht mal mehr die Schleife verlassen, weil Du als Bedingung '!=' drin hast, iReturnPayload jetzt aber größer als iPayload geworden ist ...
-
Oh vielen Dank. So habe ich das gar nicht gesehen.
Wieder mal was gelernt
Danke@Pi, laber nicht so nen Müll,sondern begründe doch mal deine erste Aussage..
-
this-> ist in praktisch allen seinen Fällen komplett redundant. Redundanter Code ist schlecht.
-
zuckerlie schrieb:
@Pi, laber nicht so nen Müll,sondern begründe doch mal deine erste Aussage..
Das ist zu offensichtlich für eine Begründung. Recherchieren kannst du selber.
-
cooky451 schrieb:
Nö, sockets sind eigentlich ziemlich simpel.
schön dass ich der einzige depp bin... und feststelle, wenn ich das internet nach brauchbaren tuts/code durchforste und verbuggten einfachsten code finde, dass die anderen auch nicht klüger sind :p
@edit: aber hey, wir sind ja schon bei 30 von 300 sloc, die für eine halbwegs vernünftige implementation nötig sind...

@edit2: und den einen fehler, den wir uns in 300 sloc erlauben dürfen haben wir auch schon mit eingebaut - toll
-
Du findest zu jedem Thema verbugten Code. Ändert aber nichts daran, dass man einfach immer testen muss, ob die Funktion erfolgreich war. Soo unglaublich komplex finde ich das jetzt nicht.

-
cooky451 schrieb:
Du findest zu jedem Thema verbugten Code. Ändert aber nichts daran, dass man einfach immer testen muss, ob die Funktion erfolgreich war. Soo unglaublich komplex finde ich das jetzt nicht.

socket und threads sind einfach etwas, was total beschissen zu testen ist.
-
Ethon schrieb:
this-> ist in praktisch allen seinen Fällen komplett redundant. Redundanter Code ist schlecht.
Danke, da werde ich mal recherchieren.

-
cooky451 schrieb:
Du findest zu jedem Thema verbugten Code. Ändert aber nichts daran, dass man einfach immer testen muss, ob die Funktion erfolgreich war. Soo unglaublich komplex finde ich das jetzt nicht.

Es ist nicht komplex. Es ist sogar so einfach, dass das drumherum einfach noch einiges machen muss. Daher sollte man eher geeignete Libraries verwenden, um das zu machen. Wir sehen hier in diesem Thread, was alles falsch gemacht werden kann.
Es gibt auch noch das EINTR. Wenn recv über ein Signal unterbrochen wird, sollte ich es möglichst noch mal aufrufen.
Auch wäre es sinnvoll, Pufferung einzubauen. Statt 42 Bytes zu lesen, wäre es sinnvoll, beispielsweise 8k zu lesen und 42 Bytes zu verarbeiten. Wenn ich dann noch weitere Daten brauche, finde ich sie bereits im Puffer und spare einen Systemaufruf. Und das kann die Performance signifikant verbessern.
Und Dein Hinweis, dass man immer testen muss, ob die Funktion erfolgreich war, ist nur halb richtig. Ich muss natürlich auf alle Fehler reagieren. Wenn ich aber eine passende Library habe, dann kann sie im Fehlerfall eine Exception auslösen. Dann kann ich den Fehler automatisch auf einer höheren Ebene verarbeiten.
Und tut mir einen Gefallen: don't feed the trolls. Spätestens wenn einer "Spinner" sagt, sollte man ihn ignorieren. Das ist kein respektvolles Verhalten gegenüber anderen Mitgliedern hier.
-
ich bins schrieb:
Wir sehen hier in diesem Thread, was alles falsch gemacht werden kann.
Nur weil ein paar Anfänger etwas falsch verwenden, ist es nicht gleich schwer es richtig zu machen. Und wenn man Exceptions will, kann man die ja werfen. Und wenn man Funktionen haben will, die eine Exception werfen wenn etwas schief gegangen ist, kann man das auch in ~3 Minuten bauen. Das kann nämlich nicht nur boost::asio. :p
Was ich damit sagen will ist, dass man nicht gleich nach einer Library schreien sollte, wenn man ein paar Bytes über das Netzt schickt. Sich darin einzuarbeiten und alles einzubinden etc. kann nämlich durchaus länger dauern, als wenn man es einfach selbst gemacht hätte. Und bei so etwas Kleinem ist die Wahrscheinlichkeit, dass man Fehler macht eigentlich eher gering.
-
Apropos EINTR. Wie würde man beim Implementieren einer solchen Library richtig auf EINTR reagieren? Man kann zwar eine Exception werfen, aber der User fängt damit wenig an.
-
Nochmal recv mit den selben Parametern aufrufen? Zumindestens wenn ich den Fehlercode richtig verstanden habe.
-
Ist der Status des Socket denn danach überhaupt definiert? Wird da nicht das bisher gelesene verworfen?
-
EINTR The receive was interrupted by delivery of a signal before any
data were available; see signal(7).Klingt für mich so, als würde nichts verworfen werden, da noch nichts gelesen wurde.
