如何尝试从超时的套接字读取数据? 我知道,select、pselect、poll,有一个超时字段,但是使用它们会禁用 tcp reno 堆栈中的“tcp fast-path”。
我唯一的想法是在循环中使用 recv(fd, ..., MSG_DONTWAIT)
最佳答案
您可以使用 setsockopt设置接收操作超时的函数:
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.
// 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
之前完成。我已经通过实验验证了它可以在 Linux 和 OS X 上的 bind
之前或之后完成。
https://stackoverflow.com/questions/2876024/