【发布时间】:2013-05-15 12:42:30
【问题描述】:
首先,我没有将其标记为关于“pselect”的问题的声誉,所以我选择了“select”。
我使用 pselect 来处理 UDP 套接字上的超时。代码如下:
UDP_STATUS udp_socket_recv(udp_socket_t* p_sock, int* p_bytes_rcvd)
{
int res = 0;
fd_set fds;
struct timespec timeout;
FD_ZERO(&fds);
FD_SET(p_sock->m_socket, &fds);
if (p_sock->m_timeout == NULL) {
res = pselect(p_sock->m_socket + 1, &fds, NULL, NULL, NULL, NULL);
} else {
timeout.tv_sec = p_sock->m_timeout->tv_sec;
timeout.tv_msec = p_sock->m_timeout->tv_usec * 1000;
res = pselect(p_sock->m_socket + 1, &fds, NULL, NULL, &timeout, NULL);
}
if (res == 0)
return UDP_TIMEOUT;
else if (res == -1) {
printf("pselect error: %s\n", strerror(errno)); /* Sometimes we end up here */
return UDP_FAILURE;
}
res = recvfrom(p_sock->m_socket, ..); /* etc etc */
}
现在,上述方法在绝大多数 的情况下都可以正常工作(尽管我可能因为无法复制/粘贴而打错了某些内容)。但是 pselect 有时会返回 -1,而 strerror(errno) 调用会打印“Interrupted system call”。
我什至不确定这就是你想要的套接字超时方式,我什至不记得我是如何想出这个解决方案的......
非常感谢任何帮助。
【问题讨论】:
-
嗯,这只是一个中断的系统调用。只需再次调用 pselect() ,这一次它会成功。 BTW
if (p_sock->m_timeout == NULL) {只有在 timeout 为 NULL 时才调用 pselect。在else { ... }的情况下,您可能也想调用 pselect()。 -
是的,很抱歉,我忘记了 else 子句中的 pselect。关于再次调用pselect,如果再次失败怎么办?