2013-04-11 83 views
7

我正在使用udp服务器/客户端应用程序。使recv_from函数无阻塞

为了确定是否有客户端关闭,服务器向客户端发送握手消息。然后,服务器等待客户端的响应发送一些数据以确保客户端处于活动状态。为此,除非客户端回复,否则服务器将阻止呼叫recvfrom(),但如果客户端关闭,服务器将无限次地阻止呼叫recvfrom()

我想在我的服务器上实现这样的功能,以便它在recvfrom()的通话中等待特定的时间(比如2秒)。如果在2秒内没有收到来自客户端的数据,则认为客户端已经死机,并返回recvfrom()

有没有办法做到这一点?我搜索互联网,但发现像设置MSG_DONTWAIT标志,当没有数据收到时立即返回的解决方案,但在我的情况下,我不想recvfrom()立即返回,但等待数据一段特定的时间,并且当没有收到数据具体的持续时间,recvfrom()函数应该重新调整。

任何帮助表示赞赏。

+1

好吧,你想实施可靠的服务。你可以设置[recvfrom()函数](http://publib.boulder.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.hala001/rcvf.htm)阻塞模式,使用[fcntl()或ioctl()函数](http://publib.boulder.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.hala001/ rcvf.htm)。另请阅读[UDP可靠的数据服务实现](http://stackoverflow.com/questions/8353970/udp-reliable-data-service-implementation) – 2013-04-11 05:46:38

+1

checkout ** [c - 设置winsock recvfrom的超时时间 - 堆栈溢出]( http://stackoverflow.com/questions/1824465/set-timeout-for-winsock-recvfrom)** – 2013-04-11 05:49:00

+1

也[check out](http://msdn.microsoft.com/en-us/library/windows/desktop /ms740120%28v=vs.85%29.aspx).it在** WSARecv()中给出了清晰的解释**(具有函数的阻塞规则)。 – 2013-04-11 05:52:22

回答

8

最简单的方法是使用setsockopt()来为有问题的套接字设置接收超时。

SO_RCVTIMEO用于此目的。

如果已经为传递给recvfrom()的套接字设置了超时,那么如果没有收到数据,函数将在此超时后返回。

例如,要设置一个10微秒读超时(根据需要从setsockopt()添加于返回值的错误检查):

#include <sys/types.h> 
#include <sys/socket.h> 

... 

struct timeval read_timeout; 
read_timeout.tv_sec = 0; 
read_timeout.tv_usec = 10; 
setsockopt(socketfd, SOL_SOCKET, SO_RCVTIMEO, &read_timeout, sizeof read_timeout); 

详细on Windows please see here,和on Linux see here和/或here (POSIX)

+0

它的工作,非常感谢你:) – Ayse 2013-04-11 06:44:30

+3

或使用'select()'等待套接字在超时内进入可读状态,则调用'recvfrom()'只有当插座实际可读时,指示数据才可用于读取。 – 2013-04-11 19:46:42

+0

我第二次使用'select'。你得到更好的控制,并且更容易升级到处理多个套接字。 – 2017-03-01 05:55:06