写过网络程序的同学,应该都知道 connect 函数,在 socket 开始读写操作之前,先要进行连接,也即 TCP 的三次握手 , 这个过程就是在 connect 函数中完成的, connect 函数本身是阻塞的,通过设置 socket 的选项及调用 select/poll 函数可以实现异步 connect 的功能
socket 默认是阻塞模式,处于阻塞模式时,调用 connect 函数之后, 会一直等待连接结果返回为止,要么成功,要么失败,connect 函数返回 0 时成功,返回 -1 失败
在局域网中,调用 connect 函数,基本上会立即返回结果,当服务器在国外时,connect 函数时会阻塞一段时间,大概几秒钟吧,具体的时间还要看当时的网络状况
为什么要用异步 connect
Linux 下 connect 默认的超时时间大概在一分钟左右(不同的Linux版本略有差别),在实际的开发中,这个时间显得有点儿长了
对于服务器来说,需要为很多的客户端服务,要尽量减少阻塞,所以,一般都是采用 异步 connect 的技术
对于每一个编写网络程序的同学来说,异步connect 应该是必须掌握的基本功
异步connect 步骤
(1) 创建socket,调用 fcntl 函数将其设置为非阻塞
(2) 调用 connect 函数,返回 0 表示连接成功,返回 -1,需要检查错误码
如果错误码为 EINPROGRESS,表示正在建立连接中
如果错误码是 EINTR 表示,表示发生了系统中断,这时继续执行连接即可
如果是其他错误码,调用 close(fd) 函数关闭 socket, 连接失败
(3) 将 socket 加入 select/poll 的可写文件描述符集合中,并设置超时时间
(4) 判断 select/poll 函数的返回值
小于等于 0 表示失败
其他,表示 socket 可写,调用 getsockopt 函数 捕获 socket 的错误信息
具体的代码如下:
/*
异步 connect 测试代码, test_connect.cpp
*/
#include <stdint.h>
#include <sys/types.h>
#