步骤1: 设置非阻塞,启动连接

实现非阻塞 connect ,首先把 sockfd 设置成非阻塞的。这样调用

connect 可以立刻返回,根据返回值和 errno 处理三种情况:

(1) 如果返回 0,表示 connect 成功。

(2) 如果返回值小于 0, errno 为 EINPROGRESS,  表示连接

建立已经启动但是尚未完成。这是期望的结果,不是真正的错误。

(3) 如果返回值小于0,errno 不是 EINPROGRESS,则连接出错了。

步骤2:判断可读和可写

然后把 sockfd 加入 select 的读写监听集合,通过 select 判断 sockfd

是否可写,处理三种情况:

(1) 如果连接建立好了,对方没有数据到达,那么 sockfd 是可写的

(2) 如果在 select 之前,连接就建立好了,而且对方的数据已到达,

那么 sockfd 是可读和可写的。

(3) 如果连接发生错误,sockfd 也是可读和可写的。

判断 connect 是否成功,就得区别 (2) 和 (3),这两种情况下 sockfd 都是

可读和可写的,区分的方法是,调用 getsockopt 检查是否出错。

步骤3:使用 getsockopt 函数检查错误

getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len)

在 sockfd 都是可读和可写的情况下,我们使用 getsockopt 来检查连接

是否出错。但这里有一个可移植性的问题。

如果发生错误,getsockopt 源自 Berkeley 的实现将在变量 error 中

返回错误,getsockopt 本身返回0;然而 Solaris 却让 getsockopt 返回 -1,

并把错误保存在 errno 变量中。所以在判断是否有错误的时候,要处理

这两种情况。

代码:

int conn_nonb(int sockfd, const struct sockaddr_in *saptr, socklen_t salen, int nsec)
{int flags, n, error, code;socklen_t len;fd_set wset;struct timeval tval;flags = fcntl(sockfd, F_GETFL, 0);fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);error = 0;if ((n = connect(sockfd, saptr, salen)) == 0) {goto done;} else if (n < 0 && errno != EINPROGRESS){return (-1);}/* Do whatever we want while the connect is taking place */FD_ZERO(&wset);FD_SET(sockfd, &wset);tval.tv_sec = nsec;tval.tv_usec = 0;if ((n = select(sockfd+1, NULL, &wset, NULL, nsec ? &tval : NULL)) == 0) {close(sockfd);  /* timeout */errno = ETIMEDOUT;return (-1);}if (FD_ISSET(sockfd, &wset)) {len = sizeof(error);code = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len);/* 如果发生错误,Solaris实现的getsockopt返回-1,* 把pending error设置给errno. Berkeley实现的* getsockopt返回0, pending error返回给error. * 我们需要处理这两种情况 */if (code < 0 || error) {close(sockfd);if (error) errno = error;return (-1);}} else {fprintf(stderr, "select error: sockfd not set");exit(0);}done:fcntl(sockfd, F_SETFL, flags);  /* restore file status flags */return (0);
}

非阻塞connect的实现相关推荐

  1. 【网络编程】非阻塞connect详解

    一.为什么使用非阻塞connect TCP连接的建立涉及一个在三路握手过程,阻塞的connect一直等到客户收到自己的SYN的ACK才返回,这需要至少一个RTT时间,RTT时间波动很大从几毫秒到几秒. ...

  2. 网络编程学习笔记(非阻塞connect)

    设置非阻塞,如果返回EINPROGRESS,表示正在建立连接,还没有完成 非阻塞的三个用途: 1.我们可以在三路握手的同时做其它的处理.connect要花一个往返时间完成,而且可以是在任何地主,从几个 ...

  3. linux下网络编程设置非阻塞,UNIX网络编程 非阻塞connect的实现

    一.<UNIX网络编程>-非阻塞connect 在一个TCP套接口被设置为非阻塞之后调用connect,connect会立即返回EINPROGRESS错误,表示连接操作正在进行中,但是仍未 ...

  4. 由select/epoll返回的非阻塞connect还会是EINPROGRESS状态吗?

    一般情况下,我们像下面代码中所示的这样使用非阻塞connect: #include <stdio.h> #include <stdlib.h> #include <str ...

  5. linux网络编程-----非阻塞connect

    libevent在内部由于使用io多路复用函数进行的事件监控,所以它所有的io读写操作都是非阻塞的,换句话说,libevent提供的接口函数evconnlistener_new_bind()和buff ...

  6. 非阻塞connect

    在 socket 是阻塞模式下 connect 函数会一直到有明确的结果才会返回(或连接成功或连接失败),如果服务器地址"较远",连接速度比较慢,connect 函数在连接过程中可 ...

  7. Linux高性能服务器I/0高级应用:非阻塞connect(15)

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

  8. Linux 非阻塞connect,错误码:EINPROGRESS

    当我们以非阻塞的方式来进行连接的时候,返回的结果如果是 -1,这并不代表这次连接发生了错误,如果它的返回结果是 EINPROGRESS,那么就代表连接还在进行中. 后面可以通过poll或者select ...

  9. 非阻塞connect,错误码:EINPROGRESS

    当我们以非阻塞的方式来进行连接的时候,返回的结果如果是 -1,这并不代表这次连接发生了错误,如果它的返回结果是 EINPROGRESS,那么就代表连接还在进行中. 后面可以通过poll或者select ...

最新文章

  1. SAP RETAIL WA01 创建分配表报错 - Plant 0000000039 Confirmation date not maintained.-
  2. arcgis python编程案例-ArcGIS Python编程案例-电子资料链接
  3. hadoop java操作hdfs
  4. WorldWind Java 版学习:1、启动过程
  5. 前手淘前端负责人:前端人如何保持竞争力?
  6. LNMP安装了哪些软件?安装目录在哪?
  7. JavaScript实现中国地图圆点标注(二十四)
  8. idea中springBoot项目修改html之类的文件后服务不自动更新
  9. day18正则表达式 的介绍和模块运用
  10. java毕业设计——基于java+Spring+SSH的CRM客户关系管理系统设计与实现(毕业论文+程序源码)——CRM客户关系管理系统
  11. python自动化转码屏幕录像专家exe为mp4
  12. Java链表-合并两个有序链表
  13. 分布式session解决方案
  14. c#加密:二、散列法 MD5、SHA256、SHA512
  15. 【HTMLCSS】运维、后端你该会的前端基本内容
  16. java程序计算鸡兔同笼_.请编写一个Java程序,能够计算鸡兔同笼问题,已知笼中共有9个头和26只脚,要求计算出该笼中有几只兔子几...
  17. A股日内回转交易意义何在?
  18. 微信企业号通过token和userId获取用户头像
  19. 寻觅反思,追求卓越——毕业工作所感
  20. thymeleaf中th:href携带参数的三种写法

热门文章

  1. python.day01笔记
  2. 【Linux开发】linux设备驱动归纳总结(一):内核的相关基础概念
  3. .NET 将数据输出到WORD、EXCEL、TXT、HTM
  4. java卸载_java快速入门篇之windows-MySQL-5.6安装与卸载
  5. 8. An Introduction to MCMC for Machine Learning (2)
  6. vue请求在退出页面还执行吗_如何用 Cloudbase Framework 部署一个 Vue 项目
  7. 【小项目关键技术七】MPU6050
  8. 【控制】《多智能体系统的动力学分析与设计》徐光辉老师-第8章-有输入时滞的二阶多智能体系统的多一致
  9. 程序的内存模型—new运算符
  10. python基础6(来自廖雪峰的官方网站)