在一个TCP套接口被设置为非阻塞之后调用connect,connect会立即返回EINPROGRESS错误,表示连接操作正在进行中,但是仍未完成;同时TCP的三路握手操作继续进行;在这之后,我们可以调用select来检查这个链接是否建立成功;非阻塞connect有三种用途:
1.我们可以在三路握手的同时做一些其它的处理.connect操作要花一个往返时间完成,而且可以是在任何地方,从几个毫秒的局域网到几百毫秒或几秒的广域网.在这段时间内我们可能有一些其他的处理想要执行;

2.由于我们使用select来等待连接的完成,因此我们可以给select设置一个时间限制,从而缩短connect的超时时间.在大多数实现中,connect的超时时间在75秒到几分钟之间.有时候应用程序想要一个更短的超时时间,使用非阻塞connect就是一种方法;

  1. timeval tm;
  2. fd_set set;
  3. unsigned long ul = 1;
  4. ioctlsocket(sock, FIONBIO, &ul); //设置为非阻塞模式
  5. bool ret = false;
  6. if (connect(...) == -1)
  7. {
  8. tm.tv_set  = TIME_OUT_TIME;
  9. tm.tv_uset = 0;
  10. FD_ZERO(&set);
  11. FD_SET(sock, &set);
  12. if (select(sock, NULL, &set, NULL, &tm) > 0)
  13. {
  14. getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
  15. if (error == 0)
  16. {
  17. ret = true;
  18. }
  19. else
  20. {
  21. ret = false;
  22. }
  23. }
  24. else
  25. {
  26. ret = false;
  27. }
  28. }
  29. else
  30. {
  31. ret = true;
  32. }
  33. ul = 0;
  34. ioctlsocket(sock, FIONBIO, &ul); //设置为阻塞模式
  35. if(!ret)
  36. {
  37. close( sockfd );
  38. printf(stderr , "Cannot Connect the server!/n");
  39. return;
  40. }
  41. printf( stderr , "Connected!/n");

代码思路:

1.建立socket
 2.将该socket设置为非阻塞模式
 3.调用connect()
 4.使用select()检查该socket描述符是否可写

5.根据select()返回的结果判断connect()结果
 6.将socket重设置为阻塞模式

所谓阻塞函数,是指其完成指定的任务之前不允许程序调用另一个函数,在Windows下还会阻塞本线程消息的发送。

所谓非阻塞函数,是指操作启动之后,如果可以立即得到结果就返回结果,否则返回表示结果需要等待的错误信息,不等待任务完成函数就返回。

首先,异步函数是非阻塞函数;

其次,获取远地信息的数据库函数是阻塞函数(因此,WinSock提供了其异步版本);

下面对具体函数做解释:

[cpp]  view plain copy
  1. int select(
  2. __in          int nfds,//本参数忽略,仅起到兼容作用
  3. __in_out      fd_set* readfds,//指向一组等待可读性检查的套接口,可为NULL
  4. __in_out      fd_set* writefds,//指向一组等待可写性检查的套接口,可为NULL
  5. __in_out      fd_set* exceptfds,//指向一组等待错误检查的套接口,可为NULL
  6. __in          const struct timeval* timeout//select()最多等待时间,对阻塞操作则为NULL
  7. );

本函数用于确定一个或多个套接口的状态。对每一个套接口,调用者可查询它的可读性、可写性及错误状态信息。用fd_set结构来表示一组等待检查的套接口

readfds参数标识等待可读性检查的套接口。如果该套接口正处于监听listen()状态,则若有连接请求到达,该套接口便被标识为可读,这样一个accept()调用保证可以无阻塞完成。对其他套接口而言,可读性意味着有排队数据供读取。或者对于SOCK_STREAM类型套接口来说,相对于该套接口的虚套接口已关闭,于是recv()或recvfrom()操作均能无阻塞完成

writefds参数标识等待可写性检查的套接口。如果一个套接口正在connect()连接(非阻塞),可写性意味着连接顺利建立。如果套接口并未处于connect()调用中,可写性意味着send()和sendto()调用将无阻塞完成。〔但并未指出这个保证在多长时间内有效,特别是在多线程环境中〕。

exceptfds参数标识等待带外数据存在性或意味错误条件检查的套接口。请注意如果设置了SO_OOBINLINE选项为假FALSE,则只能用这种方法来检查带外数据的存在与否。对于SO_STREAM类型套接口,远端造成的连接中止和KEEPALIVE错误都将被作为意味出错。如果套接口正在进行连接connect()(非阻塞方式),则连接试图的失败将会表现在exceptfds参数中。

返回值:
   select()调用返回处于就绪状态并且已经包含在fd_set结构中的描述字总数;如果超时则返回0;否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。

TCP解决connect函数的超时问题相关推荐

  1. TcpClient.Connect函数连接超时的问题(转载)

    TcpClient.Connect函数连接超时的问题 问题原述: http://topic.csdn.net/t/20060616/15/4825920.html 调用TcpClient.Connec ...

  2. 在QT中使用socket编程:解决connect函数名称冲突

    问题 当使用QT做可视化界面的时候,我们知道connect函数是连接函数,用于连接信号与槽,但connect在C/C++的socket网络编程中也是一个必不可少的函数,作用是发送连接请求,建立tcp连 ...

  3. TCP Connect 函数超时的问题

    TCP 客户端通过 connect 函数连接服务器时,若服务器此时不在线或者当前网络不正常,会在 connect 函数中阻塞(默认情况下系统使用阻塞式 socket),直到超时时间到达,而这个超时时间 ...

  4. 网络协议栈11:Connect函数分解之TCP层

    Connect函数之分解1. 首先,connect函数从参数获得远端的IP,把这个地址赋值给对应的sock结构体的对应变量,并设置了sock结构体中的一些其他变量后,首先分配(skb_buff+用户空 ...

  5. qt槽函数如何传递多个参数_Qt中connect函数不能传递参数的两种解决方法

    Qt中的connect函数可以让我们动态地管理信号和槽. 比如现在界面上有一个标签,id为label.我现在想要动态地创建一个按键,id为push,然后利用connect函数,实现点击push以后,l ...

  6. 网络编程socket之connect函数

    网络编程socket api存在一批核心接口,而这一批核心接口就是几个看似简单的函数,尽管实际上这些函数没有一个是简单.connect函数就是这些核心接口的一个函数,它完成主动连接的过程. conne ...

  7. Linux下connect函数 阻塞 与 非阻塞 问题

    一.概述 linux系统下,connect函数是阻塞的,阻塞时间的长度与系统相关.而如果把套接字设置成非阻塞,调用connect函数时会报错Operation now in progress,且err ...

  8. connect函数在阻塞和非阻塞模式下的行为

    connect函数在阻塞和非阻塞模式下的行为 当socket使用阻塞模式时,connect函数会阻塞到有明确结果才会返回,如果网络环境较差,可能要等一会,影响体验, 为了解决这个问题,我们使用异步co ...

  9. python给函数设置超时时间_在 Linux/Mac 下为Python函数添加超时时间的方法

    我们在使用 requests 这类网络请求第三方库时,可以看到它有一个参数叫做 timeout ,就是指在网络请求发出开始计算,如果超过 timeout 还没有收到返回,就抛出超时异常.(当然存在特殊 ...

最新文章

  1. 【Qt笔记】对象模型
  2. FPA笔记六 计算EI/EO/EQ的功能点
  3. Android得到一个闹钟在第三方
  4. 线框模型_进行计划之前:线框和模型
  5. phpmyadmin登陆错误:The requested URL /phpmyadmin was not found on this serve
  6. kafka 在 360 商业化的实践
  7. bigdecimal 科学计数转普通计数_LoaRunner性能测试教程:Windows计数器(2)
  8. myeclipse 安装svn(subeclipsesite)插件
  9. PS把一张白纸里的黑色图形抠出来
  10. 10个必备的AutoCAD插件
  11. 最新版Mysql安装步骤
  12. exce中让两列数据一一对应_excel表格中两组数据如何对应匹配-EXCEL让两个表格中的两列数据一一对应...
  13. mipi和isp处理_什么是ISP,他的工作原理是怎样的?
  14. 使用Photoshop制作证件照
  15. linux开启vt虚拟化,VT虚拟化如何开启
  16. 【微信小程序】云函数入门(保姆级别)
  17. Nvidia GPU的浮点计算能力(FP64/FP32/FP16)
  18. 升级IE7.0的唯一理由
  19. html去掉button的默认样式
  20. 智航学编程005(七彩虹)

热门文章

  1. python数据库操作sqlite_使用Python对SQLite数据库操作
  2. 安卓能硬改的手机机型_【每日新闻】小米11部分镜头参数爆料;华为重新采购手机零部件 重启4G手机生产...
  3. jap sql 保存_【hibernate spring data jpa】执行了save()方法 sql语句也执行了,但是数据并未插入数据库中...
  4. 水晶底是什么材质_蓝宝石水晶镜面,贵是有道理的!
  5. java中exception_Java中的异常 Exceptions
  6. 学习Java编程,英语对我们来说有多重要?
  7. html5 webrtc fir 请求关键帧_中信建投官网强调认可我们的投资理念的股民朋友请求 CTRL D 收藏、锁定本直播地址...
  8. http://www.od85c.com.cn/html/,OllyDbg script for unpacking Enigma 4.xx and 5.xx
  9. python集合数据结构_Python数据结构-集合
  10. python ui自动化测试框架_Python自动化测试框架