2010-01-27 15 views
11

He leído esto sobre la configuración de un socket para el modo sin bloqueo.¿Cómo restablecer el socket al modo de bloqueo (después de configurarlo en el modo sin bloqueo)?

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

Esto es lo que hice:

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

¿Cómo puedo configurar la toma de nuevo a modo de bloqueo? No veo una bandera O_BLOCK?

Gracias.

+0

Ver si [esta respuesta] (http://stackoverflow.com/a/18307077/514235) ayuda. – iammilind

Respuesta

14

¿Intentó borrar la marca O_NONBLOCK?

opts = opts & (~O_NONBLOCK) 
0

forma alternativa para borrar el indicador:

opts ^= O_NONBLOCK; 

Esto cambiará la bandera de no bloqueo, es decir, desactivar sin bloqueo si está habilitado actualmente.

+5

Alternar haría lo incorrecto si ya está claro. Así que simplemente elimínelo usando 'opts & = ~ O_NONBLOCK;'. Más simple y más seguro. –

5

Aquí es una solución capaz de plataforma cruzada más:

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 también tiene una función 'ioctl()' que funciona como WIN32 'ioctlsocket()'. –

+0

@AlexisWilke De hecho, sin embargo, pensé que la API para fcntl deja en claro cómo obtener los indicadores actuales para el descriptor, y aunque podría haberlo usado para la segunda llamada, estaba tratando de salvar a los lectores una posible segunda búsqueda de API. – EntangledLoops

+0

¿por qué el parámetro 'const int &'? – MikeMB

Cuestiones relacionadas