Linux:有没有超时套接字读取或recv?

我怎样才能尝试从套接字超时读取数据? 我知道,select,pselect,poll,有一个超时字段,但是使用它们会禁用tcp reno栈中的“tcp fast-path”。

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

您可以使用setsockopt函数设置接收操作的超时时间:

SO_RCVTIMEO

设置指定input​​函数等待完成的最长时间的超时值。 它接受一个timeval结构,秒数和微秒数指定了等待input操作完成的时间限制。 如果接收操作在没有接收到附加数据的情况下被阻塞了这么多时间,如果没有收到数据,它应该返回一个部分计数或错误设置为[EAGAIN]或[EWOULDBLOCK]。 此选项的默认值为零,表示接收操作不应超时。 该选项采用timeval结构。 请注意,并非所有实现都允许设置此选项。

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

这里有一个简单的代码来添加时间到您的recv函数使用轮询在C:

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

SIGALRM安装一个处理程序,然后在定期阻塞recv()之前使用alarm()ualarm() recv() 。 如果警报closures,则recv()将返回错误,并将errno设置为EINTR

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

视窗

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

注意 :您已经将此设置放在bind()函数调用之前,以便正确运行