2014-03-27 33 views
1

在我的程序中,我正在使用timeval TCP/IP套接字程序的time.h結構,其中客戶端等待此結構值指定的超時值結構初始化如下套接字不等待預期的10秒

struct timeval tv; 
tv.tv_sec = 10; 
tv.tv_usec = 0; 

並按原樣設置套接字選項。由於recv()是一個阻塞呼叫,我把超時:

setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)) ; 

並使用recv()函數接收數據。因此,爲了驗證延遲是否好,我用了兩個變量開始&停止time_t類型的:

直到數據通過接收
time_t start=clock(); 
BytesRcvd = recv(sock, CacheBuffer1, sizeof(CacheBuffer1), FLAG); 
time_t stop=clock(); 
time_t difference=difftime(stop,start); 

,從而按照定義我的期望是的recv()函數等待最多10秒插座。從服務器端我沒有發送任何東西。但是在計算差值後,我得到的值是10,但我沒有感覺到接收延遲10秒,但是在毫秒的範圍內,所以我認爲它只需要大約10 毫秒

什麼可能是問題?有什麼想法嗎?


[從評論更新]

我的插座是無阻塞的,這就是爲什麼我用setsocketopt()函數,我要等待10秒,即超時值;如果在10秒內沒有收到數據,我必須退出recv()函數...

+0

什麼是全局'errno'設置爲?你的套接字是否被阻塞?如果是這樣,那就不會永遠等下去。 'fcntl'會設置阻塞選項。 10秒的意義是什麼? – Brian

+0

我的套接字是非阻塞的,這就是爲什麼我使用setsocketopt()函數,我想等待10秒的超時值,即;如果在10秒內沒有收到數據,我必須退出recv()函數... – user3395801

+0

您可以使用'fcntl'設置阻塞選項。不'setsocketopt'。 https://stackoverflow.com/a/1549344/2591612 – Brian

回答

3

如果您的套接字是非阻塞的,即使您設置了超時,recv()也不會阻塞。

設置超時對於阻塞套接字是有意義的,不要讓它們永遠阻塞。

所以,如果你想recv()阻塞一段時間,將套接字設置爲阻塞像你那樣應用超時。

0

你的時間計算,是完全錯誤

clock()計算花費在大多數平臺的CPU時間(WINDOWS是這裏的除外)。阻塞和等待數據不會消耗大量的CPU時間。

此外,clock()返回一個clock_t,不是time_t,所以它傳遞給difftime()沒有意義。 clock()也以CLOCKS_PER_SEC爲單位,因此如果您想將時差轉換爲例如毫秒或秒。

作爲一個開始,因爲你的超時時間在幾秒鐘內,使用time()來計算它們花費的時間,結果將以秒爲單位。如果您需要更細粒度的內容,請使用gettimeofday()

time_t start=time(); 
BytesRcvd = recv(sock, CacheBuffer1, sizeof(CacheBuffer1), FLAG); 
time_t stop=time(); 
time_t difference=difftime(stop,start); 
+0

我不需要在那一刻的確切時間,只是區別接收開始和接收結束的時間,因爲clock()函數返回一個參考時間到某個值,我認爲這可能是足夠的 – user3395801

+0

@ user3395801嗯,它當然取決於平臺,但它如何測量CPU什麼時候你想檢查超時值是否被打中?即時鐘()可能會測量1微秒的CPU時間,即使您的呼叫阻塞2分鐘。無論如何你需要關心CLOCKS_PER_SEC,所以你知道你輸出的值是微秒,毫秒還是別的。 – nos