Socket-Verhalten



  • Falls die Gegenstelle weitersendet, willst Du hier aber nur die für diese Übertragung gewünschte Datenmenge lesen, deshalb:
    this->iReturnPayload += ::recv(this->sock, recvbuf+this->iReturnPayload ,iPayload - iReturnPayload, 0)



  • Bitte keine ungarische Notation und mach die ganzen this-> weg. 😮



  • sockets sind schwer... zumindest für mich! und wenn ich mich jetzt nicht täusch, sind in deinem so viele fehler (was passiert bei ::recv rückgaben von 0 bzw -1 was ja kleiner als dein NUTZDATENLAENGE ist?), dass ich dir empfehle eine fertige library zu nehmen.

    okay, evtl. wird da auch dann ganz was anderes gemacht, kenn ja ::recv nicht und will dir jetzt nichts unterstellen 🕶

    @edit warte, das ist windows... da ists statt -1 SOCKET_ERROR, oder 🙄



  • Nö, sockets sind eigentlich ziemlich simpel.
    @zuckerlie
    Für dich gibt es zwei Lösungen: select() oder Threads. (Oder poll(), aber das dürfte Windows nicht haben.) (Du kannst den Socket auch select()en nachdem er verbunden wurde, um zu testen ob du etwas Lesen kannst.)

    Und ja, du musst natürlich den Rückgabewert von recv() überprüfen bevor du das irgendwo drauf addierst, ist doch klar. Und hör auf Pi.



  • 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 🙂



  • zuckerlie schrieb:

    @Pi, spricht was dagegen?

    Spricht was dafür? 😕



  • 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 Dein

    this->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.


Anmelden zum Antworten