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

Posted armme

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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");
}

以上是关于socket 客户端编程:非阻塞式连接,错误判断及退出重连的主要内容,如果未能解决你的问题,请参考以下文章

网络编程中阻塞和非阻塞socket的区别

socket编程 ------ 客户端(非阻塞方式)

Socket编程中,阻塞与非阻塞的区别

vSocket模型详解及select应用详解

非阻塞式socket的select()用法

Socket Connect问题