我正在使用Linux系统(使用2.6.20内核的Ubuntu 7.04服务器)。选择UDP套接字在套接字关闭时不会结束 - 我做错了什么?
我有一个程序,有一个线程(thread1)等待UDP套接字的选择变得可读。 我使用select(与我的套接字作为单个readfd和单个exceptfd),而不是仅仅调用recvfrom,因为我想要超时。
从另一个线程中,我关闭并关闭了套接字。 如果我在recvfrom中阻止thread1时执行此操作,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
}
这里的SELECT语句线程1执行:
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堆栈如何工作的思考。请给我解释一下。
这将是一个很好的解决方案。在套接字和管道上都选择等待,另一个线程将写入管道以使选择返回。 – 2009-01-26 19:57:49