2013-04-11 80 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