如何尝试在超时的情况下从套接字读取数据?我知道,选择,pselect,轮询具有超时字段,但是使用它们会禁用tcp reno堆栈中的“ tcp快速路径”。
我唯一的想法是在循环中使用recv(fd,…,MSG_DONTWAIT)
您可以使用setsockopt函数来设置接收操作的超时:
SO_RCVTIMEO 设置超时值,该值指定输入函数完成之前等待的最长时间。它接受一个timeval结构,该结构的秒数和微秒数指定了等待输入操作完成的时间限制。如果接收操作阻塞了这么长时间而没有接收到其他数据,则如果没有接收到数据,它将以部分计数或errno设置为[EAGAIN]或[EWOULDBLOCK]返回。此选项的默认值为零,表示接收操作不应超时。此选项采用timeval结构。请注意,并非所有实现都允许设置此选项。
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 之前或之后完成。
bind