嘿我正在写一个udp客户端服务器,其中一个客户端等待来自服务器的数据包.但是我想限制这个等待一段时间.客户端在发出警报的某个时刻没有得到响应,基本上它出来了开始采取补救步骤.那么它的可能解决方案是什么.我认为围绕recv编写一个包装器会起作用,但是如何完成这一点,我的意思是如何在该时间限制之后让recv为你发出警报.
在这方面的任何帮助将不胜感激.
谢谢!
如果你想通过超时进行套接字通信,那么select
就是要走的路.
您基本上为各种事件设置文件描述符数组,例如read-ready或write-able,然后调用select
超时.如果其中一个事件有效,您将收到通知,您可以执行您的操作.
如果在超时之前没有发生任何事件,您仍然会收到通知,并且可以采取您认为合适的任何补救措施.
请参阅此处了解血腥细节,详见下文.
或者,您可以使用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_ZERO
和FD_SET
宏构造一组您感兴趣的文件描述符(fdsets).您可以有三个集合,一个指示一个或多个fds是否有要读取的数据,一个指示一个或多个是否准备好写入,一个指示错误.您可能不一定拥有这三个,这取决于您的代码正在做什么.
一旦你设置了fdsets,你就会传递它们,以及fds和超时的数量,select
然后编织它的魔法并返回给你.在执行此操作之前,请复制FD_COPY
fdsets以便以后恢复.
返回时,有一个错误,超时或与感兴趣的fds之一有关的事件.在后一种情况下,fdsets已被修改为仅为具有事件的fd设置fds,您可以使用它FD_ISSET
来检测哪些事件.
然后,一旦你处理了所有的事件,FD_COPY
用来恢复原始的fdsets(它们被修改select
,记住)并select
再次调用.只要你需要,继续.
请记住,错误返回select
并不一定是致命的.您可以获得(in errno
)EAGAIN
暂时的资源短缺或EINTR
处理信号.对于第二种情况,您只需重新进入选择呼叫即可.对于第一个,我想实现一个重试循环的情况下,它是只是暂时的事情.