一尘不染

Linux:是否存在超时的套接字读取或接收?

linux

如何尝试在超时的情况下从套接字读取数据?我知道,选择,pselect,轮询具有超时字段,但是使用它们会禁用tcp reno堆栈中的“ tcp快速路径”。

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


阅读 233

收藏
2020-06-02

共1个答案

一尘不染

您可以使用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);

据说在Windows上应该在调用之前完成bind。我已经通过实验验证了它可以bind在Linux和OS
X 之前或之后完成。

2020-06-02