Wie kann ich einen Socket wieder in den Blockiermodus zurücksetzen (nachdem ich ihn in den nicht blockierenden Modus gesetzt habe)?

Lesezeit: 2 Minuten

Benutzer-Avatar
n179911

Ich habe dies gelesen, um einen Socket in den nicht blockierenden Modus zu versetzen.

http://www.gnu.org/software/libc/manual/html_mono/libc.html#File-Status-Flags

Folgendes habe ich getan:

static void setnonblocking(int sock)
{
    int opts;

    opts = fcntl(sock,F_GETFL);
    if (opts < 0) {
        perror("fcntl(F_GETFL)");
        exit(EXIT_FAILURE);
    }
    opts = (opts | O_NONBLOCK);
    if (fcntl(sock,F_SETFL,opts) < 0) {
        perror("fcntl(F_SETFL)");
        exit(EXIT_FAILURE);
    }
    return;
}

Wie kann ich die Steckdose wieder in den Sperrmodus versetzen? Ich sehe kein O_BLOCK-Flag?

Vielen Dank.

  • Sehen Sie, ob diese Antwort hilft.

    – iammilind

    19. Mai 2016 um 10:54 Uhr

Haben Sie versucht, das O_NONBLOCK-Flag zu löschen?

opts = opts & (~O_NONBLOCK)

Benutzer-Avatar
Verschränkte Schleifen

Hier ist eine plattformübergreifende Lösung:

bool set_blocking_mode(int socket, bool is_blocking)
{
    bool ret = true;

#ifdef WIN32
    /// @note windows sockets are created in blocking mode by default
    // currently on windows, there is no easy way to obtain the socket's current blocking mode since WSAIsBlocking was deprecated
    u_long non_blocking = is_blocking ? 0 : 1;
    ret = NO_ERROR == ioctlsocket(socket, FIONBIO, &non_blocking);
#else
    const int flags = fcntl(socket, F_GETFL, 0);
    if ((flags & O_NONBLOCK) && !is_blocking) { info("set_blocking_mode(): socket was already in non-blocking mode"); return ret; }
    if (!(flags & O_NONBLOCK) && is_blocking) { info("set_blocking_mode(): socket was already in blocking mode"); return ret; }
    ret = 0 == fcntl(socket, F_SETFL, is_blocking ? flags ^ O_NONBLOCK : flags | O_NONBLOCK));
#endif

    return ret;
}

  • Linux hat auch eine ioctl() Funktion, die wie WIN32 funktioniert ioctlsocket().

    – Alexis Wilke

    6. Dezember 2015 um 1:46 Uhr

  • @AlexisWilke Tatsächlich dachte ich jedoch, dass die API für fcntl klar macht, wie die aktuellen Flags für den Deskriptor abgerufen werden können, und obwohl ich sie für den zweiten Aufruf hätte verwenden können, versuchte ich, den Lesern eine potenzielle zweite API-Suche zu ersparen.

    – Verschränkte Schleifen

    7. Dezember 2015 um 17:09 Uhr


  • warum zum const int & Parameter?

    – MikeMB

    15. September 2016 um 12:55 Uhr

  • @MikeMB Nur ein Artefakt, wo ich dieses Beispiel aus meiner Codebasis extrahiert habe. Nicht nötig.

    – Verschränkte Schleifen

    15. September 2016 um 14:43 Uhr

Benutzer-Avatar
Eswald

Alternative Möglichkeit zum Löschen der Flagge:

opts ^= O_NONBLOCK;

Dadurch wird das Non-Blocking-Flag umgeschaltet, dh Non-Blocking wird deaktiviert, wenn es derzeit aktiviert ist.

  • Umschalten würde das Falsche tun, wenn es bereits klar ist. Also einfach löschen mit opts &= ~O_NONBLOCK;. Einfacher und sicherer.

    – Craig McQueen

    16. April 2015 um 2:20 Uhr

1055620cookie-checkWie kann ich einen Socket wieder in den Blockiermodus zurücksetzen (nachdem ich ihn in den nicht blockierenden Modus gesetzt habe)?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy