连接超时
调用connect
连接到远程主机时,若网络发生拥塞,TCP可能会执行多次超时重传,这将耗费不短的时间,所以我们会想要为connect
设置连接的超时。考虑到select
可以设置一个超时时间,所以我们会使用select
来实现这个功能。
我们实现一个函数connect_timeout
:
其实现并不复杂,首先我们将 socket 设置成非阻塞的,然后调用connect
,如果connect
返回0
就说明连接已经建立了,如果返回-1
并且错误码是EINPROGRESS
,这说明connect
正处在建立连接的过程中,返回其它错误码则表示connect
调用失败。
很明显,既然connect
正在建立连接,那么它就有可能成功也有可能失败。那么我们可以调用select
并且设置一个超时,等待connect
建立连接、超时或失败。如果connect
成功建立连接,则需要将 socket 重新设置成阻塞的。
在select
成功返回之后,我们需要判断 socket 的可读写状况,如果它是不可读也不可写的,也就是说连接建立失败。
注意,如果连接建立失败,那么 socket 是既可读又可写的。但是还有另一种情况,如果在调用connect
和select
之间,socket 接收到数据,那么在select
返回之后,socket 也是既可读又可写的。所以这里要用到getsockopt
来判断 socket 是否发生错误。