2010-06-10 18 views
5

Pregunta breve
¿Cuál es la forma correcta de manejar un evento Ctrl-C enviado a través de Telnet en el lado del servidor?Sockets POSIX: ¿Cómo detectar Ctrl-C enviado a través de Telnet?

pregunta larga
Después de llamar a recv() en un socket, me gustaría manejar algunas situaciones adecuadamente. Uno de ellos es devolver un cierto código de error cuando se recibió Ctrl-C. ¿Cuál es la forma correcta de detectar esto? Las siguientes obras, pero simplemente no parece correcto:

size_t recv_count; 
static char ctrl_c[5] = {0xff, 0xf4, 0xff, 0xfd, 0x06}; 

recv_count = recv(socket, buffer, buffer_size, 0); 

if (recv_count == sizeof(ctrl_c) && 
    memcmp(buffer, ctrl_c, sizeof(ctrl_c) == 0) 
{ 
    return CTRL_C_RECEIVED; 
} 

me encontré con un comentario en Ctrl-C en una nota lateral en this UNIX Socket Preguntas:

[...] (por cierto, fuera de banda se usa a menudo para ese ctrl-C, también).

Según tengo entendido, la recepción de datos fuera de banda se realiza utilizando recv() con un determinado indicador como último parámetro. Pero cuando estoy esperando datos usando recv() como lo hago en el código anterior, no puedo leer datos fuera de banda al mismo tiempo. Aparte de eso, estoy obteniendo algo usando recv() sin esa oob-bandera.

+0

Ctrl-D es enviado por telnet como^D (0x04) carácter –

Respuesta

2

Configure el socket como no bloqueante con fcntl(), use select() (pselect() en algunos sistemas) para verificar los datos que llegan. Así es como muestrear la condición actual de un socket, es decir, si tiene datos para recv() y si puede aceptar un envío(), o si hay una excepción. No te quedes sentado bloqueando.

A recv() devuelve tanta información disponible como el tamaño del búfer suministrado puede contener. Si el socket se ha configurado para recibir datos fuera de banda (opción de socket SO_OOBINLINE) y no hay datos OOB no leídos, solo se devuelven los datos fuera de banda. Llame a ioctl() SIOCATMARK para determinar si hay más datos fuera de banda que no se leen.

Cuando recibe datos OOB no puede recv() más allá del final del paquete OOB en una sola llamada a recv(), por lo que es irracional en ese sentido.

No sé lo que se considera la mejor práctica, pero la idea de tomar ctrl-c por delante de otros datos de socket ya almacenados es una buena idea.

+0

En realidad, estoy escribiendo una biblioteca para uso interno que ofrece funciones convenientes para sockets (ya hay algunos fcntl() y select() allí), por lo que este problema no es específico de la implementación de una aplicación concreta, sino más bien "simplemente otra cosa con la que mi genial biblioteca puede ayudar". Esperaba ver eventos como ctrl-c sin datos OOB para hacerlo simple. Estoy de acuerdo en no solo sentarme en recv() y esperar y mi biblioteca admite modos de bloqueo y no bloqueo, pero hubiera sido bueno implementar esto una vez y funciona siempre (tm). De todos modos, ¡gracias por la respuesta! –

+0

http://linux.softpedia.com/get/Programming/Libraries/sWrapper-35278.shtml –

+0

El enlace de arriba es un ejemplo de algunos esfuerzos similares para hacer que los sockets estén menos involucrados. IMO, el enfoque más complicado le permite ajustar la configuración según sus necesidades. las 'necesidades exactas' pueden ser difíciles de hacer sin agregar muchas opciones complejas en su código. Lo que deshace la intención de su esfuerzo, de alguna manera. –

Cuestiones relacionadas