非阻塞connect
- 调用fcntl设置套接字为非阻塞
- 发起非阻塞connect。期望的错误是EINPROCESS,表示连接已经启动但是尚未建立。
- 如果非阻塞connect返回0,表示连接已经建立,当客户端和服务端位于同一主机时连接很快,有可能出现这种情况
- 调用select设置超时时间,然后等待套接字变为可读或可写。当select返回0时,表示connect超时;
- 如果描述符变为可读或可写,由于错误情况下套接字也是可读可写的,所以要区分这种情况下是否真的连接成功,这时我们调用getsockopt取得套接字的待处理错误
- 还原套接字的阻塞状态并返回
注意:
使用 getsockopt 函数检查错误
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len)
在 sockfd 都是可读和可写的情况下,我们使用 getsockopt 来检查连接
是否出错。但这里有一个可移植性的问题。
如果发生错误,getsockopt 源自 Berkeley 的实现将在变量 error 中
返回错误,getsockopt 本身返回0;然而 Solaris 却让 getsockopt 返回 -1,
并把错误保存在 errno 变量中。所以在判断是否有错误的时候,要处理
这两种情况。
具体源程序如下:
|
|
为send/recv设置超时时长
|
|
如果recv或者send返回-1,而且errno为EAGIN表示超时。具体可以使用man recv查看说明如下:
|
|
参考链接:
非阻塞connect的实现