由于网上大部分教程为阻塞方式连接,当项目需要大量连接从机的情况下,阻塞式连接socket会导致长时间卡顿。因此需要用非阻塞式的方式连接,并设置超时是时间,再设置会阻塞。下属C++编辑代码实测可用,代码如下:

SOCKET s;

ctx->s为 socket的套接字,自己定义即可

int rc;
    struct sockaddr_in addr;
    modbus_tcp_t *ctx_tcp = ctx->backend_data;

#ifdef OS_WIN32
    if (_modbus_tcp_init_win32() == -1) {
        return -1;
    }
#endif

ctx->s = socket(PF_INET, SOCK_STREAM, 0);
    if (ctx->s == -1) {
        return -1;
    }

rc = setsockopt(ctx->s, IPPROTO_TCP, TCP_NODELAY,
                    (const void *)&option, sizeof(int));
    if (rc == -1) {
        return -1;
    }

if (ctx->debug) {
        printf("Connecting to %s\n", ctx_tcp->ip);
    }

//想办法将链接设置为非阻塞,链接完成后再设置为阻塞 william 0924

unsigned long ul = 1;
    rc = ioctlsocket(ctx->s, FIONBIO, (unsigned long*)&ul);
    if (rc == SOCKET_ERROR)
        return -1;

//bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(ctx_tcp->port);
    addr.sin_addr.s_addr = inet_addr(ctx_tcp->ip);

rc = connect(ctx->s, (struct sockaddr *)&addr,
                 sizeof(struct sockaddr_in));

TIMEVAL tm = { 1,0 };//设置超时时间1s
    fd_set rset;
    fd_set wset;
    unsigned long mode = 1;

//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式 william 0924
    if (rc)
    {
        rc = WSAGetLastError();
        if (WSAEWOULDBLOCK == rc)/*!<如果Resource temporarily unavailable.10035*/
        {
            FD_ZERO(&rset);
            FD_ZERO(&wset);
            FD_SET(ctx->s, &rset);
            FD_SET(ctx->s, &wset);
        
            rc = select(ctx->s + 1, &rset, &wset, NULL, &tm);
            if (rc<0)
            {
                close(ctx->s);
                return -1;
            }
            else if (rc == 0)/*!<Time Out*/
            {
                close(ctx->s);
                return -1;
            }
            else
            {
                if (FD_ISSET(ctx->s, &wset))/*!<如果可写,说明连接好*/
                {
                    mode = 0;
                    rc = ioctlsocket(ctx->s, FIONBIO, &mode); /*!<再次设置为阻塞模式 */
                    if (rc)
                    {
                        close(ctx->s);
                        return -1;
                    }
                     ///*!<正确退出*/
                    return 0;
                }
                else
                {
                    // /*!<不可写*/
                    close(ctx->s);
                    return -1;
                }
            }
        }//    end if(WSAEWOULDBLOCK==ret)
         else
        {
    //    /*!<网络出现其他错误*/
             close(ctx->s);
            return -1;
        }
    }
    else
    {
        return 0;
    }

//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式

return 0;

C++ TCP socket 非阻塞连接超时设定方式相关推荐

  1. boost库之socket 非阻塞/缓冲区大小等属性设置

    boost库之socket 非阻塞/缓冲区大小等属性设置 原文:http://blog.csdn.net/byxdaz/article/details/77318219 asio socket 非阻塞 ...

  2. php socket非阻塞,php stream_set_blocking设置非阻塞模式,php stream_set_blocking影响函数fgets()和fread()...

    stream_set_blocking函数可以将资源流设置为阻塞模式或者非阻塞模式,主要影响的函数分别是fgets,fread,其他的手册没有说. 在socket编程中,如果一个socket连接上了, ...

  3. 阻塞、非阻塞、超时(同步与异步)

    今天看RXW文档,看到这个概念,不知啥意思... 1.阻塞: 阻塞==同步->例如:发送消息 直到 发送成功 才能发送下一条消息 接收消息 这条消息接收完毕 才能接收下条消息 2.非阻塞 非阻塞 ...

  4. 非阻塞的connect使用方式

    connect 函数的调用涉及到3次握手,默认connect函数为阻塞连接状态. 通常connect 会阻塞到三次握手的完成和失败,而这个connect阻塞超时时间会依赖于系统,一般为75s到几分钟时 ...

  5. 怎样实现一个非阻塞的超时重试任务队列

    起因 最近接手一个项目,要把其中的阻塞任务队列,重构成非阻塞.在客户端很少有机会直接处理任务队列.项目完成需要总结经验 阻塞的发生 我这里先说明我遇到的阻塞问题,我这里的阻塞不是多线程访问的阻塞,概念 ...

  6. epoll关于ET、LT模式和socket非阻塞模式的几个总结

    epoll的ET和LT模式 LT水平触发是默认的模式,只要缓冲区有消息就会触发,如果这次事件没有被处理,那么下一次调用epoll_wait的时候,事件仍然会被触发:ET边沿触发只会在第一次有消息的时候 ...

  7. Java nio Socket非阻塞模式

    NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有 事件发生时,他会通知我们,传回一组Select ...

  8. java 阻塞 socket_java socket非阻塞I/O

    1      非阻塞(Nonblocking)体系结构 在这一部分,我将从理论的角度来解释非阻塞体系的结构及其工作原理.这部"喜剧"(当然,如果你喜欢的话也可以称做戏剧)的&quo ...

  9. Socket 非阻塞模式下connect 返回EINPROGRESS(115)错误

    今天再测试socket的时候,发现一个很奇怪的问题,就是客户端再connect的时候第一次connect总是会返回-1,errno是115,往往第二次连接就可以成功了.但是对于服务端来说,第一次连接已 ...

最新文章

  1. 恒生java开发复试_2019恒生电子面试经验(JAVA开发人员,实施工程师等)
  2. c 语言bool 类型数据_C ++中的bool数据类型
  3. Scrapy 爬虫框架初体验三 —— 工程优化及其完善
  4. oracle timestamp计算两分钟前_阿里数据库真的超过Oracle了么?
  5. macappstore登不上去_丈夫在外与多人暧昧,妻子气愤不已,可他却怒怼:这还不都是你逼的...
  6. java.lang.stringind_为什么越界了? java.lang.StringIndexOutOfBoundsException
  7. SQL删除字段重复内容且保留唯一一条数据
  8. 热门加壳工具VMProtect v3.1发布,新增内存保护,性能改进|附下载
  9. Adobe Bridge 2020新增功能
  10. linux iptable 使用指南
  11. python升序和降序排序_sql升序和降序(orderby升序和降序排列显示)
  12. CBDB中国历代人物历史可视化系统
  13. 如何美化菜单界面java_用 Java 创建带图像的菜单来美化界面
  14. Oracle的Replace函数与translate函数详解与比较
  15. 麒麟座V3.1接入OneNET平台初体验--上传温湿度
  16. vue.js3D立方体旋转播放特效
  17. 分库分表实战(第1期):一叶知秋 —— 图览分库分表外卖订单项目
  18. html简单的文字自动出现效果,8个华丽的HTML5文字动画特效赏析
  19. 装linux系统的工具箱,PE,Dos工具箱,自动安装linux的U盘制作
  20. 51单片机使用 8线/4线/PCF8574(I2C) 驱动 LCD1602

热门文章

  1. cheatsheet 常用图标大全
  2. poj 2573 Bridge(有A、B、C、D四个人,要在夜里过一座桥……)
  3. golang websocket 聊天室demo
  4. Unity Application Block 发布
  5. linux中禁用Root帐户的4种方法
  6. Linux系统扩展oracle数据库所在的分区
  7. EFK6.3+kafka+logstash日志分析平台集群
  8. CentOS7中密码登录失败锁定设置
  9. JAVA异常分类和处理
  10. Java中常见的URL问题及解决方案