non-blocking sockets - HTTP - Client-Seitig



  • Wenn du überall return machst brauchst du aber auch kein else if mehr.



  • tntnet schrieb:

    Das ist doch genau die Art und Weise, wie Du kommunizierst. Ich würde auf die "XYZ" aussage nicht mit einem Affront reagieren und meinem Kommunikationspartner angreifen, indem ich sage, dass er halluziniert.

    Finde ich nicht. Wenn ich, wie du es formulierst, freundlich und respektvoll darauf aufmerksam mache, dann schone ich vielleicht deine Gefühle, aber du lernst dadurch nicht, es künftig zu vermeiden. Dadurch, dass ich direkt das Faktum nenne, wirst du in der Zukunft versuchen, diese Negativität zu vermeiden und die Texte deines Gegenüber korrekt zu lesen. Sonst ist der Anreiz einfach nicht groß genug.

    Es kostet mich mehr Mühe und Zeit, fehlerhafte Aussagen durchzulesen und zu korrigieren, als dich, sie direkt korrekt niederzuschreiben.

    Ob du das dadurch tust, indem du dein Umfeld änderst, oder indem du dich änderst, ist mir dann relativ latte. Ich bin nur halt gerne von Leuten umgeben, die schlauer sind als ich.

    tntnet schrieb:

    Der Backlog Parameter sagt nicht aus, wie viele Verbindungen der Socket aufnehmen kann. Er sagt lediglich aus, wie viele Verbindungsanfragen gesammelt werden, die noch nicht mit accept angenommen wurden. Schreibe ich einen Server, werde ich jede Verbindung unmittelbar mit accept annehmen und damit den Backlog abbauen.

    man listen(2) schrieb:

    The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow.

    Hm. Ich habe immer "pending connections" als die Anzahl an Verbindungen gelesen, die der Socket offen haben lassen kann, nicht als die Anzahl an Verbindungen, die der Kernel noch vorhält. Aber der Absatz macht wohl deutlich, dass du recht hast:

    man listen(2) schrieb:

    The behavior of the backlog argument on TCP sockets changed with Linux 2.2. Now it specifies the queue length for completely established sockets waiting to be accepted, instead of the number of incomplete connection requests.

    tntnet schrieb:

    Es ist so klarer.

    Ach?

    void HeaderParser::state_protocol0(char ch)
    {
        if (ch == ' ' || ch == '\t')
            return;
    
        if (!std::isalpha(ch))
        {
            log_warn("invalid character " << chartoprint(ch) << " in http protocol field");
            state = &HeaderParser::state_error;
            return;
        }
    
        token.reserve(32);
        token = ch;
        state = &HeaderParser::state_protocol;
        return;
    }
    

    Du findest also, dass das nicht klarer aussieht? Wenn ich mir die Funktion durchlese, sehe ich:

    "Aha, wenn das Zeichen ein Whitespace ist, raus! Super! Aus den Augen, aus dem Sinn.
    Wenn std::isalpha meint, es ist keines, loggen, Fehlerstatus setzen, raus! Wieder super!
    Invaliditätsprüfung ist durch, jetzt geht's an Fleisch der Funktion: reserviere Speicher, packe das Zeichen schonmal rein, und markiere, dass es schonmal ganz gut aussieht."

    Bei deinem Code denke ich:

    "Aha, wenn das Zeichen ein Whitespace ist, raus! Super! Aus den Augen, aus dem Sinn ... nee, warte mal. Wenn nicht, dann prüfen, ob std::isalpha meint, es ist eines. Wenn es eines ist, dann ... ist das das Fleisch der Funktion? Reserviere Speicher, packe das Zeichen da rein, und markiere, dass es schonmal ganz gut aussieht? Sieht so aus. Ansonsten ... das heißt, wenn es kein Zeichen im Alphabet ist ... dann logge und setze Fehlerstatus."

    Merke, wie ich beim ersten Mal direkt annehme, dass es sich hier um die Prüfung auf Korrektheit handelt (Invaliditätsprüfung). Das ist ein vertrautes Konzept, damit kann der Leser sofort arbeiten. Das habe ich kein einziges Mal bei dir im Code gedacht.

    tntnet schrieb:

    Das ist übrigens auch eine schöne Stelle, wo Daten vom Socket gelesen werden und gleich verworfen werden, da sie nicht relevant sind.

    Das habe ich auch nicht angegriffen. Ich habe bereits gesagt, dass dein Code cache-lokaler ist als meiner, was durchaus ein Vorteil sein kann.

    Auf der anderen Seite speichere ich mir ja auch mein Layout ab, und die Daten werden so oder so durch den Cache geschliffen (Schreiben von Kernel- in Userspace). Solange ich also beim nächsten recv dann wieder mit dem Prüfen anfange, macht mir das gar nichts, die neusten Daten sind bereits im Cache.

    Was ist, wenn ich große Requests absetze? File-Upload bspw.? Oder bei Responses? Vielleicht habe ich die Antwort nur übersehen, aber gesehen habe ich noch keine.

    EDIT: Warum immer dieser Code hier?

    token.reserve(32);
    token = ch;
    state = &HeaderParser::state_protocol;
    

    Nach dem dritten mal würde ich mir denken: "Komm, machen wir mal 'ne Funktion draus:

    /*Bin gerade zu faul, den Typen von state zu suchen ...*/
    inline void add_token
    (
        state_type new_state,
        char ch,
        size_t reserve_size
    )
    {
        token.reserve(reserve_size);
        token = ch;
        state = new_state;
    }
    

    , und fertig ist die Laube."

    Wenn ich ganz lustig wäre, dann würde ich noch eine inline-Funktion schreiben:

    inline void add_token_with_default_size
    (
        state_type new_state,
        char ch
    )
    {
        add_token(new_state,ch,32);
    }
    


  • Ok ich hab mir den Code jetzt auch mal kurz angesehen.

    Tausend Zeilen Code für so einen popeligen Header? Dann ein Funktionsaufruf per Zeichen noch dazu? Das find ich recht erschlagend.

    Warum benutzt du keine Streams. Den ganzen Header-Parser hättest du auch mit 3 Methoden und 50 Zeilen Code machen können. Fehlerprüfung inklusive.



  • Ob man jetzt if else oder return oder sonst was schreibt ist denke ich mal relativ egal. So wie es ist, finde ich es schon einigermaßen lesbar. Ich glaube, dass das nicht wirklich relevant ist. Ich habe es mir ja schon verziehen. Vielleicht tut ihr es ja auch.

    @Blockade: Und so ein paar poplige Header sind das nicht. Schau Dir rfc 2616 an. Wenn Du jede Nuance ganz allgemeingültig unterstützen möchstest, ist das nicht mit ein paar string.find-Funktionen getan. Schau Dir einfach mal die continuation header an. Da wird es immer schwerer. Einen stateful parser finde ich persönlich einfacher zu warten und robuster. Es hat sich bewährt.

    Ein einfacher Parser ist schnell geschrieben aber ein robuster vollständig standardkonformer macht da schon ein wenig mehr Arbeit.

    Und ja, es werden Streams benutzt. Ich weiß nicht, wo Du an der Stelle Streams sehen willst.

    Es ist auch Code, den man als normaler Benutzer nicht beachten muss. Dafür sind ja Libraries da.



  • dachschaden schrieb:

    tntnet schrieb:

    Das ist doch genau die Art und Weise, wie Du kommunizierst. Ich würde auf die "XYZ" aussage nicht mit einem Affront reagieren und meinem Kommunikationspartner angreifen, indem ich sage, dass er halluziniert.

    Finde ich nicht. Wenn ich, wie du es formulierst, freundlich und respektvoll darauf aufmerksam mache, dann schone ich vielleicht deine Gefühle, aber du lernst dadurch nicht, es künftig zu vermeiden. Dadurch, dass ich direkt das Faktum nenne, wirst du in der Zukunft versuchen, diese Negativität zu vermeiden und die Texte deines Gegenüber korrekt zu lesen. Sonst ist der Anreiz einfach nicht groß genug.

    Ach, das ist wieder das. Du hältst Dich für unfehlbar. Wenn einer was falsch versteht, was Du gesagt hast, muss der Kommunkationspartner halluzinieren. Dass Du etwas unverständlich formulierst ist völlig undenkbar und Du musst unbedingt und in aller Deutlichkeit dieses Faktum betonen, dass der Partner Deine Aussage nicht korrekt gelesen hat. Und Du musst auch den Kommunikationpartner erziehen, dass er doch Deine ach so wertvollen und wohlformulierten Worte korrekt zu lesen hat. Das nenn ich mal überheblich und "Ego-Trip".



  • tntnet schrieb:

    Ach, das ist wieder das. Du hältst Dich für unfehlbar. Wenn einer was falsch versteht, was Du gesagt hast, muss der Kommunkationspartner halluzinieren. Dass Du etwas unverständlich formulierst ist völlig undenkbar und Du musst unbedingt und in aller Deutlichkeit dieses Faktum betonen, dass der Partner Deine Aussage nicht korrekt gelesen hat.

    OK, jetzt reicht's.

    Gerade erst in dem letzten Post habe ich zugegeben, dass ich die verschissene Manpage nicht richtig gelesen habe. Das kann man als Halluzination interpretieren. Ich hätte es sogar verstanden. Aber vor allem: ich hatte erwartet, dass du das auch raffst.

    Tust du nicht. Confirmation Bias. Alles, was dir gefällt, sieht du, das andere siehst du nicht. Du halluzinierst gerade wieder und siehst es nicht einmal. Kannst du gerne als Beleidigung auffassen.

    Viel Spaß noch auf deiner Halluzination.



  • Ja.

    Ihr habt mir den halben Thread zugekackt.



  • Blockade schrieb:

    Ihr habt mir den halben Thread zugekackt.

    YMMD 😃 😃 😃



  • Blockade schrieb:

    Ja.

    Ihr habt mir den halben Thread zugekackt.

    War die andere Hälfte denn wenigstens hilfreich? Wenn ja, dann bin ich zufrieden. Wenn Nein, dann können wir gerne noch über die eigentliche Frage diskutieren.

    Ich würde mir aber eine gepflegte Ausdrucksweise wünschen 😉 .

    Dachschaden hat ja gesagt, dass es ihm reicht. Ich fürchte, er hält sich nicht dran, aber wir können es ja mal versuchen.


  • Mod

    hä? schrieb:

    SeppJ warum greifst du hier komischerweise nicht ein?

    Weil's ein obskurer Thread im Linuxforum ist.


Anmelden zum Antworten