选择UDP套接字时关闭套接字并没有结束 - 我究竟做错了什么? [英] select on UDP socket doesn't end when socket is closed - what am I doing wrong?

查看:237
本文介绍了选择UDP套接字时关闭套接字并没有结束 - 我究竟做错了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的Linux系统上(Ubuntu的7.04服务器与2.6.20的内核)。

I'm working on Linux system (Ubuntu 7.04 server with a 2.6.20 kernel).

我得等待一个选择的UDP套接字变得可读,有一个线程(线程1)的程序。
我使用select(我的插座作为单一readfd和单exceptfd),而不是只调用recvfrom的,因为我想超时。

I've got a program that has a thread (thread1) waiting on a select for a UDP socket to become readable. I'm using the select (with my socket as the single readfd and the single exceptfd) instead of just calling recvfrom because I want a timeout.

从另一个线程,我关机和关闭套接字。
如果我这样做线程1被阻塞在recvfrom的同时,那么recvfrom的将立即终止。
如果我这样做,而线程1被挡在选择了超时,那么选择不会立即终止,但最终将超时正常。

From another thread, I shutdown and close the socket. If I do this while thread1 is blocked in a recvfrom, then the recvfrom will terminate immediately. If I do this while thread1 is blocked in a select with a timeout, then the select will NOT terminate immediately, but will eventually timeout properly.

谁能告诉我,为什么它是选择不尽快关闭套接字退出?这不是一个例外?我可以看到它不是可读的(明显),但它是封闭的,这似乎是要exeptional。

Can anyone tell me why it is that the select doesn't exit as soon as the socket is closed? Isn't that an exception? I can see where it isn't readable (obviously), but it's closed, which seems to be to be exeptional.

下面是插座的开口(搬运删除了所有的错误让事情变得简单):

Here's the opening of the socket (all error handling removed to keep things simple):

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:

Here's the select statement that thread1 executes:

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

更新:显然,(如下所述),关闭套接字不是一个特殊的条件(从选择的角度来看)。我想我需要知道的是:为什么?而且,这是故意的?

UPDATE: Obviously (as stated below), closing the socket isn't an exceptional condition (from select's point of view). I think what I need to know is: Why? And, Is that intentional?.

我真的想了解这背后的选择行为,思想,因为它似乎违背我的期望。因此,我显然需要调整我的TCP协议栈是如何工作的思考。请解释一下。

I REALLY want to understand the thinking behind this select behavior because it seems counter to my expectations. Thus, I obviously need to adjust my thinking on how the TCP stack works. Please explain it to me.

推荐答案

也许你应该用别的东西来唤醒选择。也许管道或类似的东西。

Maybe you should use something else to wake up the select. Maybe a pipe or something like that.

这篇关于选择UDP套接字时关闭套接字并没有结束 - 我究竟做错了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆