2010-01-27 4 views
11

Ich habe das in Bezug auf das Setzen eines Sockets auf nicht blockierenden Modus gelesen.Wie setze ich einen Socket zurück in den blockierenden Modus (nachdem ich ihn in den nicht blockierenden Modus gesetzt habe)?

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

Hier ist, was ich getan habe:

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 den Socket zurück Modus Blockieren? Ich sehe kein O_BLOCK-Flag?

Vielen Dank.

+0

Sehen Sie, wenn [diese Antwort] (http://stackoverflow.com/a/18307077/514235) hilft. – iammilind

Antwort

14

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

opts = opts & (~O_NONBLOCK) 
0

Alternative Art und Weise, die die Flagge zu löschen:

opts ^= O_NONBLOCK; 

Dies wird das Non-Blocking-Flag umschalten, das heißt deaktivieren non-blocking, wenn zur Zeit aktiviert. Hier

+5

Toggling würde das falsche tun, wenn es schon klar ist. Also lösche es einfach mit 'opts & = ~ O_NONBLOCK;'. Einfacher und sicherer. –

5

ist eine Cross-Plattform fähig Lösung:

bool set_blocking_mode(const 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; 
} 
+0

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

+0

@AlexisWilke Tatsächlich dachte ich, dass die API für fcntl klarstellt, wie man die aktuellen Flags für den Deskriptor erhält, und obwohl ich es für den zweiten Aufruf hätte verwenden können, versuchte ich, Lesern eine mögliche zweite API-Suche zu ersparen. – EntangledLoops

+0

warum der 'const int &' Parameter? – MikeMB

Verwandte Themen