2010-01-27 12 views
11

Ho letto questo per quanto riguarda l'impostazione di un socket in modalità non bloccante.Come reimpostare un socket in modalità blocco (dopo averlo impostato in modalità non bloccante)?

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

Ecco quello che ho fatto:

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; 
} 

Come posso impostare il socket torna alla modalità di blocco? Non vedo una bandiera O_BLOCK?

Grazie.

+0

Vedi se [questa risposta] (http://stackoverflow.com/a/18307077/514235) aiuta. – iammilind

risposta

14

Hai provato a cancellare il flag O_NONBLOCK?

opts = opts & (~O_NONBLOCK) 
0

modo alternativo per cancellare il flag:

opts ^= O_NONBLOCK; 

Ciò consente di passare dalla non bloccante bandiera, cioè disabilitare non bloccante se attualmente abilitato.

+5

La commutazione farebbe la cosa sbagliata se è già chiara. Quindi basta cancellarlo usando 'opts & = ~ O_NONBLOCK;'. Più semplice e più sicuro. –

5

Ecco un altro cross-platform soluzione in grado:

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 ha anche una funzione 'ioctl()' che funziona come 'ioctlsocket()'. –

+0

@AlexisWilke Effettivamente, tuttavia, pensavo che l'API per fcntl rendesse chiaro come ottenere i flag correnti per il descrittore e, sebbene potessi usarlo per la seconda chiamata, stavo cercando di salvare i lettori una potenziale seconda ricerca API. – EntangledLoops

+0

perché il parametro 'const int &'? – MikeMB

Problemi correlati