繁体   English   中英

设置套接字recv TCP的超时时间

[英]setting timeout for socket recv TCP

我找到了一些关于如何做的提示,但我不明白如何使用setsockopt。 我有一个无限的while循环调用recv,我想超时并close(cli_socket)如果客户端在5秒内没有发送任何东西。

如果客户端只发送整个预期消息的一部分,我想重置计时器并再给他5秒钟。

currentry我有这个:

while((cut = buffer.find("\r\n")) == -1)
        {
            struct timeval tv;
            tv.tv_sec = 5;
            setsockopt(cli_socket, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval));
            recv(cli_socket, tmpBuffer, 100, 0);
            buffer += tmpBuffer;
            memset(tmpBuffer, 0, 100);
        }

如果它是EAGAINEWOULDBLOCK你应该测试recv的返回并break你的循环:

EAGAIN或EWOULDBLOCK
套接字被标记为非阻塞,接收操作将被阻止,或者已设置接收超时,并且在收到数据之前超时已到期

struct timeval tv = {5, 0};
setsockopt(cli_socket, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)&tv, sizeof(struct timeval));

while((cut = buffer.find("\r\n")) == -1)
{
    int numBytes = recv(cli_socket, tmpBuffer, 100, 0));

    /// Edit: recv does not return EAGAIN else, it return -1 on error.
    /// and in case of timeout, errno is set to EAGAIN or EWOULDBLOCK

    if (numBytes <= 0)
    {
        // nothing received from client in last 5 seconds
        break;
    }

    buffer.append(tmpBuffer, numBytes);
}

您也可以使用不那么复杂的select函数:

while((cut = buffer.find("\r\n")) == -1)
{
    timeval timeout = { 5, 0 };
    fd_set in_set;

    FD_ZERO(&in_set);
    FD_SET(cli_socket, &in_set);

    // select the set
    int cnt = select(cli_socket + 1, &in_set, NULL, NULL, &timeout);

    if (FD_ISSET(cli_socket, &in_set))
    {
        int numBytes = recv(cli_socket, tmpBuffer, 100, 0));
        if (numBytes <= 0)
        {
            // nothing received from client
            break;
        }

        buffer.append(tmpBuffer, numBytes);
    }
    else
    {
        // nothing received from client in last 5 seconds
        break;       
    }
}

暂无
暂无

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

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