Я работаю в системе Linux (сервер Ubuntu 7.04 с ядром 2.6.20).
У меня есть программа, в которой есть поток (thread1), ожидающий выбора, чтобы сокет UDP стал читабельным.
Я использую select (с моим сокетом в качестве единственного readfd и единственного кромеfd) вместо того, чтобы просто вызывать recvfrom, потому что я хочу тайм-аут.
Из другого потока отключаю и закрываю сокет.
Если я сделаю это, когда thread1 заблокирован в recvfrom, то recvfrom немедленно прекратит работу.
Если я сделаю это, в то время как thread1 заблокирован в выборе с тайм-аутом, тогда выбор НЕ завершится немедленно, но в конечном итоге истечет правильно.
Может кто-нибудь сказать мне, почему выбор не завершается, как только сокет закрывается? Разве это не исключение? Я вижу, где он не читается (очевидно), но он закрыт, что кажется исключительным.
Вот открытие сокета (вся обработка ошибок убрана для простоты):
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
}
Вот оператор выбора, который выполняет thread1:
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);
ОБНОВЛЕНИЕ: Очевидно (как указано ниже), закрытие сокета не является исключительным условием (с точки зрения select). Я думаю, что мне нужно знать: почему? И это намеренно?
Я ДЕЙСТВИТЕЛЬНО хочу понять, что стоит за этим избранным поведением, потому что оно противоречит моим ожиданиям. Таким образом, мне, очевидно, необходимо скорректировать свое мышление о том, как работает стек TCP. Пожалуйста, объясни мне это.