码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-02-22 16:57:40      阅读:413      评论:0      收藏:0      [点我收藏+]

标签:ESS   sleep   class   sizeof   操作   执行   打开   soc   情况下   

本文将探讨 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 客户端编程:非阻塞式连接,错误判断及退出重连

标签:ESS   sleep   class   sizeof   操作   执行   打开   soc   情况下   

原文地址:https://www.cnblogs.com/armme/p/10419079.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!