NONBlocking/Blocking Socket in Schleife



  • Hallo Leute,

    ich habe da mal eine Frage, da ich nichts gefunden habe. Wenn ich einen einfachen Socket über die Socket-Funktion(socket(...,...,...) erstelle, dann ist dieser ja im "Blocking Modus". Pseudo-Bsp.:

    while(true){
    
    TuDies();
    
    recv(socket,buffer,buffergröße,Flag); 
    //wartet bis daten erhalten, wenn daten erhalten, mach weiter
    
    TuDas();
    }
    

    Dies hat zur Folge, dass die while schleife bei recv stehen bleibt und solang wartet bis er Daten bekommt und die Daten erhalten hat?!

    Aber ich habe jetzt zwei Prozesse die miteinander kommunizieren. Prozess A und Prozess B. Prozess B hat eine Schleife, welche immer wieder durcharbeiten muss!

    Jetzt muss ich Prozess A die Möglichkeit geben, dem Prozess B etwas über den Socket zu senden. Das ist auch kein Problem, allerdings soll dies natürlich nur geschehen, wenn Prozess A es möchte oder der User interagiert.
    D.h das Prozess B bei jedem Schleifendurchlauf auch ein nonblocking recv aufruft und schaut ob er was erhält. Pseudo-Bsp.:

    while(true){
    TueDies();
    
    recv(bla) // auf nonblocking socket, wenn keine daten im puffer stehen, mach //weiter
    if(bla == "CLOSE")
    break;
    
    TuDas();
    }
    

    Wenn Prozess A nun etwas an Prozess B schickt und nonblocking recv Daten erhält, wartet es allerdings auch solange, bis die Daten vollständig erhalten sind, wenn keine Daten da sind, läuft die Schleife einfach weiter?

    Lange Rede, kurzer Sinn: Wenn ein ein recv auf einen Nonblocking Socket aufgerufen wird, keine Daten erhält wartet es nicht, sondern lässt den Programmcode weiterlaufen. Falls es jedoch Daten erhält, dann wartet recv solange bis alle Daten übertragen sind?!

    Danke im Voraus

    //edit: Ich konnte noch nie so fehlerfrei besoffen schreiben und habe jetzt locker 15 minuten gebraucht. Und jetzt fällt mir auf, dass ich ja recv nutze und das ja im Endeffekt "BSD"-Nachbauten sind. Also könnte es einfach nur in C++ rein, also notfalls verschieben :L)



  • zuckerlie schrieb:

    Lange Rede, kurzer Sinn: Wenn ein ein recv auf einen Nonblocking Socket aufgerufen wird, keine Daten erhält wartet es nicht, sondern lässt den Programmcode weiterlaufen. Falls es jedoch Daten erhält, dann wartet recv solange bis alle Daten übertragen sind?!

    recv() auf einen non-blocking Stream-Socket wartet gar nicht. Es liest so viel Daten wie "gerade da sind", und aus dem internen Empfangspuffer gelesen werden können ohne zu blockieren. Deswegen nennt man die Dinger ja auch non-blocking 😉

    Nochwas:

    Stream-Sockets sind reine Byte-Streams.
    Stream-Sockets kennen keine Nachrichten bzw. zusammengehörenden Blöcke.
    Wenn du in einen Stream-Socket an einem Ende was reintust, dann wird das irgendwann vollständig und in der richtigen Reihenfolge am anderen Ende wieder rauskommen.
    Die "Aufteilung" in einzelne Stücke die hintereinander an send() übergeben wurden bleibt dabei allerdings in keiner Weise erhalten.

    Und, was auch oft falsch verstanden wird: auch recv() auf einen blocking Socket wartet nicht, bis es den übergebenen Puffer voll machen kann. recv() auf einen blocking Socket wartet nur so lange, bis es wenigstens ein Byte an Daten zurückgeben kann.



  • Erstmal vielen Dank! Wieder etwas dazu gelernt 🙂

    Ich war die Nacht ein bisschen verballert :p

    Nochmal zum Verständnis.

    Beim blocking Socket
    Eine recv() Abfrage schaut nach, ob Daten im Datenpuffer sind, wenn nein, wartet er so lange bis Daten im Datenpuffer enthalten sind, fragt diese (vollständig) ab, und der Programmablauf geht weiter.

    Beim nonblocking Socket
    Schaut, ob Daten im Datenpuffer enthalten sind, wenn nein, geht der Programmablauf einfach weiter. Wenn die nächste Abfrage auf den Nonblocking Socket aufgerufen wird und Daten im Datenpuffer erhalten sind, fragt er diese ( vollständig) ab und macht dann weiter mit dem Programmablauf?

    Das Programm A und B arbeiten zuerst mit blocking Sockets. Machen einen selbstgeschrieben Handshake. Dann soll Programm B ca. jede Minute einige Bytes and Programm A schicken(blocking und timeoutfunc.) die soviel heißen wie "Ich lebe noch". Das ist kein Problem und funktiert auch.

    Jetzt möchte ich allerdings in Prozess B - innerhalb der main-schleife - bei jedem Durchlauf eine Abfrage auf den verbunden Socket setzt und falls dann nichtmal ein Byte vorhanden ist mache einfach weiter und warte nicht bis Bytes im Puffer stehen. D.h hier nutz ich einen NonBlocking-Socket?!


Anmelden zum Antworten