是否有從套接字讀取或矩形超時?

[英]Linux: is there a read or recv from socket with timeout?


How can I try to read data from socket with timeout? I know, select, pselect, poll, has a timeout field, but using of them disables "tcp fast-path" in tcp reno stack.

如何嘗試使用超時讀取套接字的數據?我知道,select, pselect, poll,有一個超時字段,但是使用它們將禁用tcp reno棧中的“tcp快速路徑”。

The only idea I have is to use recv(fd, ..., MSG_DONTWAIT) in a loop

我唯一的想法是使用recv(fd,……)在循環中

5 个解决方案

#1


152  

You can use the setsockopt function to set a timeout on receive operations:

您可以使用setsockopt函數設置接收操作超時:

SO_RCVTIMEO

SO_RCVTIMEO

Sets the timeout value that specifies the maximum amount of time an input function waits until it completes. It accepts a timeval structure with the number of seconds and microseconds specifying the limit on how long to wait for an input operation to complete. If a receive operation has blocked for this much time without receiving additional data, it shall return with a partial count or errno set to [EAGAIN] or [EWOULDBLOCK] if no data is received. The default for this option is zero, which indicates that a receive operation shall not time out. This option takes a timeval structure. Note that not all implementations allow this option to be set.

設置超時值,該超時值指定輸入函數等待完成的最大時間量。它接受具有秒數和微秒數的時間結構,指定等待輸入操作完成的時間限制。如果一個接收操作阻塞了這么長時間而沒有接收到其他數據,那么如果沒有接收到數據,它將返回一個部分計數或設置為[EAGAIN]或[eif dblock]的errno。此選項的默認值為零,這表明接收操作不應該超時。這個選項需要一個時間結構。注意,並非所有實現都允許設置此選項。

// 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 on Windows this should be done before calling bind. I have verified by experiment that it can be done either before or after bind on Linux and OS X.

據報道,在Windows上,這應該在調用bind之前完成。我通過實驗驗證了它可以在Linux和OS X上綁定之前或之后執行。

#2


15  

Here's a Simple code to add time out to your recv function using poll in C:

這里有一個簡單的代碼,可以使用C中的poll向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;
}

#3


0  

Install a handler for SIGALRM, then use alarm() or ualarm() before a regular blocking recv(). If the alarm goes off, the recv() will return an error with errno set to EINTR.

為SIGALRM安裝一個處理程序,然后在常規的阻塞recv()之前使用alarm()或ualarm()。如果警報響起,recv()將返回一個錯誤,並將errno設置為EINTR。

#4


0  

// works also after bind operation for WINDOWS

//在WINDOWS綁定操作之后也可以工作

DWORD timeout = timeout_in_seconds * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);

#5


-3  

LINUX

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));

NOTE: You have put this setting before bind() function call for proper run

注意:您已經將此設置放在bind()函數調用之前,以便正常運行


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2010/05/20/eaf8872d057e621aeecd3a2b86d3e17a.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com