如何识别套接字是否已超时或没有其他数据?
我有这个:
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;
}
Run Code Online (Sandbox Code Playgroud)
之后我检查EWOULDBLOCK或EAGAIN设置,但即使超时没有发生,他们被设置.我需要执行不同的操作,具体取决于连接时间是否成功或者我是否已成功阅读
有三种方法可以检查超时:
使用SO_RCVTIMEO(我假设你正在做,你真的应该展示那部分!).然后你将errno设置为EWOULDBLOCK或EAGAIN.如果你得到这个错误对你有阻塞套接字知道它已经超时,否则该功能不会与特定错误集中返回.对于非阻塞套接字,这种方法毫无意义.
另请注意,setsockopt()此选项的参数在不同平台上有所不同.在POSIX平台上,参数是指向a的指针struct timeval,而在Windows上它是指向a的指针DWORD.另请注意,在Windows上,该recv函数实际上会在超时时返回 WSAETIMEDOUT.
如果套接字超时使用,SO_RCVTIMEO则它处于不确定状态,不应再使用.关闭它并重新连接.
使用SO_KEEPALIVE.没有标准或平台无关的设置超时的方法,默认为两个小时.的recv通话将失败,并errno设置为ETIMEDOUT.
将keep-alive信令添加到您的协议中.
使用方法一,在POSIX平台(如Linux或OSX)上,您可以检查这样的内容
l = recv(...)
if (l < 0)
{
if (errno == EWOULDBLOCK || errno == EAGAIN)
{
// Timeout, handle it somehow
}
break; // Exit receiving loop
}
Run Code Online (Sandbox Code Playgroud)
这里的重要部分是不检查,errno除非你确实知道有错误.如果recv返回非负值,那么值errno是不确定的.
您还需要检查两者 EWOULDBLOCK,EAGAIN因为没有指定它们中的哪一个将被设置.