C++ 阻塞socket,能否设置超时时间

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ 阻塞socket,能否设置超时时间相关的知识,希望对你有一定的参考价值。

参考技术A
setsockopt函数可以
参考技术B int timeout=1000;
setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(const char*)&timeout,sizeof(int));
setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeout,sizeof(int));

//以上只有winsock 2支持,UNIX、LINUX及WINSOCK1不支持。本回答被提问者和网友采纳

socket 客户端编程:非阻塞式连接,错误判断及退出重连

本文将探讨 socket 客户端的非阻塞式连接,连接成功后的错误判断及退出重连。

1. 连接方法

关于socket 客户端的非阻塞 connect 编程,网上找到的实现方式一般都是,
套接字创建之后,默认是阻塞式的,对其执行 connect 操作,如果服务端在监听,则会成功建立连接,但这只是理想情况。如果服务端没有开启,或是网络异常呢,connect 会一直阻塞到连接超时,这个超时时间在 Linux 下一般是 75 s 到几分钟。那么,如果在服务端未打开的时候 connect,连接建立会阻塞,即便服务端在这时候开启,connect 也必须在到达超时时间返回之后,才能执行下一次 connect,成功建立连接。也就是说,成功建立连接所需的时间最长是套接字的超时时间,而 75 s 是我们不能忍受的。我们要做的就是将 socket 设置为非阻塞模式,connect 成功与否都立即返回,以便及时响应服务端的监听。

网上一般的实现方式是,直接将 connect 设置为非阻塞模式,这种方法只有在 client, server 在同一台主机情况下,会成功建立连接返回,一般情况下,都不能建立连接返回 -1,errno 置为 EINPROGRESS,于是需要利用 select 判断 socket 的连接建立状态。具体实现参考 https://blog.csdn.net/nphyez/article/details/10268723

以上实现方式比较繁琐,我的方法是,为阻塞式 socket 设置超时时间,准确地说,是调用 setsockopt 设置发送超时时间,设置了超时的阻塞式 socket 跟非阻塞 socket 操作起来是类似的,而且避免了有远程主机监听时仍然返回 -1 的情况,不用再调用 select 来做连接判断。实现代码为

while(1)
{
    sock = socket(PF_INET, SOCK_STREAM, 0);
    if (sock == -1)
    {
        LOG4CXX_WARN(logger, "Create NAVI client socket error");
        goto exit;
    }
    if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &send_timeout, sizeof(send_timeout)) != 0)
    {
        LOG4CXX_WARN(logger, "NAVI client socket set send timeout option error");
    }
    if (connect(sock, (struct sockaddr*) &serv_addr, sizeof (serv_addr)) == -1)
    {
        LOG4CXX_WARN(logger, "NAVI client socket connect error, " << errno << ", " << strerror(errno));
        close(sock);
        sleep(2);
        continue;
    }
    LOG4CXX_INFO(logger, "Connected to NAVI server");
}

以上是关于C++ 阻塞socket,能否设置超时时间的主要内容,如果未能解决你的问题,请参考以下文章

Java:这两种设置Socket超时时间的方法有啥不同吗?

linux socket阻塞recv怎么返回

如何在python的socket recv方法上设置超时?

一定要为HttpUrlConnection设置connectTimeout属性以防止连接被阻塞

如何在 boost asio 中设置阻塞套接字的超时时间?

tcpsocket/tmp很慢