C,C ++中的中断机制

时间:2010-05-26 09:28:50

标签: c++ c sockets

嘿我正在编写一个udp客户端服务器,其中一个客户端等待来自服务器的数据包。但是我想限制这段时间等待一段时间。客户端在发出警报后的某个时刻没有得到响应,基本上它出来并开始采取补救措施。那么它的可能解决方案是什么。我认为围绕recv编写一个包装器会起作用,但是如何完成这个,我的意思是如何在该时间限制之后让recv为你发出警报。

在这方面的任何帮助将不胜感激。

谢谢!

2 个答案:

答案 0 :(得分:6)

如果你想通过超时进行套接字通信,那么select就可以了。

您基本上为各种事件设置文件描述符数组,例如read-ready或write-able,然后在超时时调用select。如果其中一个事件有效,您将收到通知,您可以执行您的操作。

如果在超时之前没有发生任何事件,您仍然会收到通知,并且可以采取您认为合适的任何补救措施。

有关详细信息,请参阅here,详见下文。

或者,您可以将setsockopt与SO_RCVTIMEO:

一起使用
struct timeval tv;
tv.tv_sec = 5;
tv.tv_used = 0;
setsockopt (socket_id, SOL_SOCKET, SO_RCVTIMEO,
    &tv, sizeof(struct timeval));

有关select的详细信息,请使用FD_ZEROFD_SET宏构建一组您感兴趣的文件描述符(fdsets)。您可以有三个集合,一个指示一个或多个fds是否有要读取的数据,一个指示一个或多个是否准备好写入,一个指示错误。您可能不一定拥有这三个,这取决于您的代码正在做什么。

一旦你设置了fdsets,你将它们连同fds的数量和超时一起传递给select,它编织它的魔法并返回给你。在执行此操作之前,请复制(FD_COPY)fdsets以供以后恢复。

返回时,可能存在错误,超时或与其中一个感兴趣的事件相关的事件。在后一种情况下,fdsets已被修改为仅为具有事件的人设置了fds,您可以使用FD_ISSET来检测哪些事件。

然后,在您处理完所有事件后,使用FD_COPY恢复原始fdsets(它们已由select修改,请记住)并再次调用select。只要你需要,就继续。

请记住,从select返回错误并不一定是致命的。您可以(errnoEAGAIN获取临时资源短缺,或EINTR如果处理了信号。对于第二种情况,您只需重新进入选择呼叫即可。对于第一个,我会实现一个重试循环,以防 只是一个临时的事情。

答案 1 :(得分:1)

您可以将select(...)作为最后一个参数使用非零超时。这是最便携的方式。

您也可以使用信号,但这不是可移植的,即使在拥有它的系统上,它也可能无法像您预期的那样工作。 (一旦信号处理程序完成,recv / select /可能会重新启动,从而击败整个目的。)