[英]TCP socket timeout or no data to read
如何确定套接字超时还是没有其他数据?
我有这个:
setsockopt(cli_socket, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)&tv, sizeof(struct timeval)); //5 sec timeout
while(1)
{
l = recv(socket, ...);
if(l < 0)
break;
}
在我检查是否设置了EWOULDBLOCK
或EAGAIN
,即使没有发生超时也已设置它们。 我需要执行不同的操作,具体取决于连接超时还是成功完成读取
有三种检查超时的选项:
使用SO_RCVTIMEO
(我假设您正在做,您确实应该显示该部分!)。 然后,您将errno
设置为EWOULDBLOCK
或EAGAIN
。 如果你得到这个错误,你知道它已经超时阻塞插座上,否则该功能不会与特定错误集中返回。 对于非阻塞套接字,此方法没有任何意义。
另请注意,此选项的setsockopt()
参数在不同平台上有所不同。 在POSIX平台上,参数是指向struct timeval
的指针,而在Windows上,则是指向DWORD
的指针。 还要注意,在Windows上, recv
函数实际上在超时时返回 WSAETIMEDOUT
。
如果套接字使用SO_RCVTIMEO
超时,则它处于不确定状态,不应再使用。 关闭它并重新连接。
使用SO_KEEPALIVE
。 没有标准的或与平台无关的方法来设置超时,默认时间为两个小时左右。 recv
调用应该失败,并且errno
设置为ETIMEDOUT
。
将保持活动信令添加到协议中。
使用方法一,在POSIX平台(如Linux或OSX)上,检查类似以下内容
l = recv(...)
if (l < 0)
{
if (errno == EWOULDBLOCK || errno == EAGAIN)
{
// Timeout, handle it somehow
}
break; // Exit receiving loop
}
此处的重要部分是不要检查errno
除非您实际上知道有错误。 如果recv
返回非负值,则errno
的值不确定。
你还需要检查这两个 EWOULDBLOCK
和EAGAIN
因为它没有指定哪些人将被设置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.