本节来将客户端的connect
阻塞式改为非阻塞式. 这样可以同时向服务端发起多个连接并一起进行处理, 非阻塞connect
一般用来测试服务端的抗压能力.
connect 非阻塞用途
connect
设置为非阻塞之后会立即返回 设置errno为 EINPROGRESS
错误, 表示连接操作正在进行中, 但是仍未完成连接; 同时TCP的三次握手操作继续进行. 之后, 可以调用 select
来检查连接是否成功.
其非阻塞connect
有三种用途 :
- 可以在三路握手的同时做一些其它的处理. 这段时间可能几毫秒但也可能几百毫秒.
- 可以同时建立多个连接. 在Web浏览器中很普遍.
- 可以使用
select
(或者IO复用其他函数) 来等待连接的完成, 因此可以给select
设置时间限制, 从而缩短connect
的超时时间. 毕竟大多数中,connect
的超时时间在75秒到几分钟之间. 我们就可以通过connect
非阻塞来设置更短的超时时间.
connect 连接注意的细节
connect
的细节还有一些需要注意哦, 不然很容易处理错误 :
- 即使套接口是非阻塞的, 如果连接的服务器在同一台主机上, 那么调用
connect
建立连接时, 连接通常会立即建立成功. - 源自Berkeley 的实现 (和POSIX) 有两条与 select 和非阻塞 connect 相关的两条规则:
- 当连接建立成功时, 套接口描述符变成可写;
- 当连接出错时, 套接口描述符变成既可读又可写;
注意:当一个套接口出错时,它会被select调用标记为既可读又可写.
connect 超时设置
connect
没有超时设置, 但是我们可以将其设置为非阻塞式, 由select
来设置超时即可. 在写代码时要注意上述的细节处理哦.
完整代码 :
客服端 : timeout_client.c
服务端 : service.c
客服端部分代码 :
// connect 超时封装
int timeout_connect(int sockfd, struct sockaddr *addr, socklen_t socklen, int nsec){
int oldfd;
int r