我怎樣才能嘗試從超時套接字讀取數據? 我知道,select,pselect,poll,有一個超時字段,但是使用它們會禁用tcp reno棧中的「tcp fast-path」。Linux:有沒有從超時套接字讀取或recv?
我唯一的想法是使用的recv(FD,...,MSG_DONTWAIT)在一個循環
我怎樣才能嘗試從超時套接字讀取數據? 我知道,select,pselect,poll,有一個超時字段,但是使用它們會禁用tcp reno棧中的「tcp fast-path」。Linux:有沒有從超時套接字讀取或recv?
我唯一的想法是使用的recv(FD,...,MSG_DONTWAIT)在一個循環
可以使用setsockopt函數來設置超時的接收操作:
SO_RCVTIMEO
設置指定 輸入 功能等待,直到它的最大時間量的超時值完成。它 接受與 秒數和微秒 指定上多久 等待極限,用於將輸入到操作完成 以timeval結構。如果接收操作已阻塞爲 這麼多時間而不 接收附加數據,應當 返回與部分計數或errno 設置爲[EAGAIN]或者如果沒有 數據被接收[EWOULDBLOCK]。此 選項的默認值爲零,這表示 接收操作不應超時。 該選項採用timeval結構。 請注意,並非所有實施 都允許設置此選項。
// LINUX
struct timeval tv;
tv.tv_sec = timeout_in_seconds;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
// WINDOWS
DWORD timeout = timeout_in_seconds * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
// MAC OS X (identical to Linux)
struct timeval tv;
tv.tv_sec = timeout_in_seconds;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
Reportedly在Windows這應該叫bind
之前完成。我已經通過實驗證實,它可以完成之前或bind
在Linux和OS X.後
爲SIGALRM
安裝一個處理程序,那麼之前經常阻塞recv()
使用alarm()
或ualarm()
。如果警報消失,recv()
將返回一個錯誤errno
設置爲EINTR
。
報警(和信號)是錯誤的方式本任務。如果我想使用tcp快速路徑,比我需要最小的延遲。信號很慢。 – osgx 2010-06-04 13:35:17
@osgx信號僅在超時時發生。 – 2015-11-03 23:04:30
這裏有一個簡單的代碼在C添加時間來使用輪詢您的recv函數:
struct pollfd fd;
int ret;
fd.fd = mySocket; // your socket handler
fd.events = POLLIN;
ret = poll(&fd, 1, 1000); // 1 second for timeout
switch (ret) {
case -1:
// Error
break;
case 0:
// Timeout
break;
default:
recv(mySocket,buf,sizeof(buf), 0); // get your data
break;
}
LINUX
struct timeval tv;
tv.tv_sec = 30; // 30 Secs Timeout
tv.tv_usec = 0; // Not init'ing this can cause strange errors
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv,sizeof(struct timeval));
WINDOWS
DWORD timeout = SOCKET_READ_TIMEOUT_SEC * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
注意:你已經把這個設置之前bind()
函數調用正確的運行
這個問題已經在幾年前回答了。你的解決方案帶來了什麼新的價值? – 2017-08-30 10:39:32
你已經把這個設置放在bind()函數調用之前,正確運行這部分在ans裏沒有提到 – vivek 2017-09-08 10:17:58
也有使用線程的選擇:)但信號線仍然需要 – osgx 2010-06-04 13:36:05