Estoy trabajando en un sistema Linux (servidor Ubuntu 7.04 con kernel 2.6.20).seleccionar en el socket UDP no termina cuando se cierra el socket - ¿Qué estoy haciendo mal?
Tengo un programa que tiene un hilo (thread1) esperando en una selección para que un socket UDP sea legible. Estoy usando la selección (con mi socket como lectura única y el único exceptofd) en lugar de simplemente llamar a recvfrom porque quiero un tiempo de espera.
De otro hilo, apago y cierro el socket. Si hago esto mientras thread1 está bloqueado en un recvfrom, entonces el recvfrom terminará inmediatamente. Si hago esto mientras thread1 está bloqueado en una selección con un tiempo de espera, la selección NO terminará inmediatamente, pero eventualmente terminará correctamente.
¿Alguien puede decirme por qué la selección no se cierra tan pronto como se cierra la toma? ¿No es eso una excepción? Puedo ver que no es legible (obviamente), pero está cerrado, lo que parece ser excepcional.
Aquí está la apertura de la toma (todo el manejo de errores retira para mantener las cosas simples):
m_sockfd = socket(PF_INET, SOCK_DGRAM, 0);
struct sockaddr_in si_me;
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(port);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(m_sockfd, (struct sockaddr *)(&si_me), sizeof(si_me)) < 0)
{
// deal with error
}
Aquí está la instrucción select que Thread1 ejecuta:
struct timeval to;
to.tv_sec = timeout_ms/1000;// just the seconds portion
to.tv_usec = (timeout_ms%1000)*1000;// just the milliseconds
// converted to microseconds
// watch our one fd for readability or
// exceptions.
fd_set readfds, exceptfds;
FD_ZERO(&readfds);
FD_SET(m_sockfd, &readfds);
FD_ZERO(&exceptfds);
FD_SET(m_sockfd, &exceptfds);
int nsel = select(m_sockfd+1, &readfds, NULL, &exceptfds, &to);
ACTUALIZACIÓN: Es evidente que (como se indica a continuación), cerrar el zócalo no es una condición excepcional (desde el punto de vista de selección). Creo que lo que necesito saber es: ¿Por qué? Y, es eso intencional ?.
REALMENTE quiero entender el pensamiento detrás de este comportamiento selecto porque parece contrario a mis expectativas. Por lo tanto, obviamente necesito ajustar mi pensamiento sobre cómo funciona la pila de TCP. Por favor, explícamelo.
Esa sería una buena solución. Haga que la selección espere tanto en el zócalo como en la tubería, y el otro hilo escribiría en la tubería para hacer que la selección regrese. –
Eso funcionaría y probablemente sea con lo que termine. Solo quería evitar cualquier parte móvil adicional. ¡Gracias! –