TCP套接字超时或没有要读取的数据

TCP套接字超时或没有要读取的数据,c,sockets,C,Sockets,如何识别套接字是否超时或是否没有进一步的数据 我有这个: 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; } setsockopt(cli_socket,SOL_socket,SO_RCV

如何识别套接字是否超时或是否没有进一步的数据

我有这个:

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;
}
setsockopt(cli_socket,SOL_socket,SO_RCVTIMEO,(struct timeval*)和tv,sizeof(struct timeval))//5秒超时
而(1)
{
l=recv(插座,…);
if(l<0)
打破
}

在我检查是否设置了
ewoodblock
EAGAIN
之后,即使没有发生超时,也会设置它们。我需要执行不同的操作,这取决于连接是否超时或我是否成功读取了

您必须检查是否设置了ETIMEDOUT。 从

埃蒂米德 连接在建立连接期间超时,或由于活动连接上的传输超时


有三个选项可用于检查超时:

  • 使用
    SO\u RCVTIMEO
    (我假设您正在这样做,您真的应该显示该部分!)。然后将
    errno
    设置为
    ewoodblock
    EAGAIN
    。如果在阻塞套接字上出现此错误,则知道它已超时,否则函数将不会返回特定的错误集。对于非阻塞套接字,此方法没有意义

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

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

  • 使用
    以便保持可用性
    。没有标准的或独立于平台的方式来设置超时,默认为两个小时。当
    errno
    设置为
    ETIMEDOUT
    时,
    recv
    调用应该失败

  • 将保持活动的信令添加到协议中


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

    l = recv(...)
    if (l < 0)
    {
        if (errno == EWOULDBLOCK || errno == EAGAIN)
        {
            // Timeout, handle it somehow
        }
    
        break;  // Exit receiving loop
    }
    
    l=recv(…)
    if(l<0)
    {
    if(errno==ewoldblock | | errno==EAGAIN)
    {
    //超时,怎么处理
    }
    break;//退出接收循环
    }
    
    这里重要的一点是不要检查
    errno
    ,除非您确实知道有错误。如果
    recv
    返回非负值,则
    errno
    的值不确定


    您还需要检查
    ewoodblock
    EAGAIN
    ,因为没有指定将设置其中的哪一个。

    您所说的“即使没有发生超时,也会设置它们”是什么意思?它们不能同时被“设置”,因为它们是
    errno
    的可能值,并且它们不相等。我的意思是,即使我不想,我也会陷入if状态,但这与
    errno==ewoodblock
    errno==EAGAIN
    完全不同。阅读手册,它说,如果连接关闭,recv将返回0,如果超时,0表示您读取了一些内容。您错了。即使没有发生超时,也不会设置它们。您需要先检查
    recv()
    是否返回-1,然后再检查
    errno
    。先前系统调用的剩余值不会被成功的系统调用所干扰。OP正在使用
    recv()
    ,因此“连接建立期间”或“由于活动连接上的传输超时”不会发生超时。有人能告诉我“由于活动连接上的传输超时”是什么意思吗?使用“recv”时的“传输”是什么意思?您能举个例子吗?我想我的条件顺序不对