当套接字关闭时,UDP套接字上的选择不会结束 - 我做错了什么? [英] select on UDP socket doesn't end when socket is closed - what am I doing wrong?

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

问题描述

我正在使用 Linux 系统(带有 2.6.20 内核的 Ubuntu 7.04 服务器).

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

我有一个程序有一个线程 (thread1) 等待一个 UDP 套接字的选择变得可读.我正在使用 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.

从另一个线程,我关闭并关闭了套接字.如果我在 thread1 在 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.

谁能告诉我为什么一旦套接字关闭,选择就不会退出?那不是例外吗?我可以看到它在哪里不可读(显然),但它已关闭,这似乎是例外.

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
}

这是 thread1 执行的 select 语句:

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

更新:显然(如下所述),关闭套接字不是例外情况(从 select 的角度来看).我想我需要知道的是:为什么?而且,这是故意的吗?

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天全站免登陆