繁体   English   中英

TCP套接字超时或无数据可读取

[英]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;
}

在我检查是否设置了EWOULDBLOCKEAGAIN ,即使没有发生超时也已设置它们。 我需要执行不同的操作,具体取决于连接超时还是成功完成读取

有三种检查超时的选项:

  1. 使用SO_RCVTIMEO (我假设您正在做,您确实应该显示该部分!)。 然后,您将errno设置为EWOULDBLOCKEAGAIN 如果你得到这个错误,你知道它已经超时阻塞插座上,否则该功能不会与特定错误集中返回。 对于非阻塞套接字,此方法没有任何意义。

    另请注意,此选项的setsockopt()参数在不同平台上有所不同。 在POSIX平台上,参数是指向struct timeval的指针,而在Windows上,则是指向DWORD的指针。 还要注意,在Windows上, recv函数实际上在超时时返回 WSAETIMEDOUT

    如果套接字使用SO_RCVTIMEO超时,则它处于不确定状态,不应再使用。 关闭它并重新连接。

  2. 使用SO_KEEPALIVE 没有标准的或与平台无关的方法来设置超时,默认时间为两个小时左右。 recv调用应该失败,并且errno设置为ETIMEDOUT

  3. 将保持活动信令添加到协议中。


使用方法一,在POSIX平台(如Linux或OSX)上,检查类似以下内容

l = recv(...)
if (l < 0)
{
    if (errno == EWOULDBLOCK || errno == EAGAIN)
    {
        // Timeout, handle it somehow
    }

    break;  // Exit receiving loop
}

此处的重要部分是不要检查errno除非您实际上知道有错误。 如果recv返回非负值,则errno的值不确定。

你还需要检查这两个 EWOULDBLOCKEAGAIN因为它没有指定哪些人将被设置。

您必须检查是否设置了ETIMEDOUT。 recv(3)手册页中:

ETIMEDOUT连接建立期间或活动连接上的传输超时导致连接超时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM