我怎样才能尝试从超时套接字读取数据? 我知道,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