客户端使用非阻塞socket进行connect的流程
问题
使用非阻塞( non-blocking
) socket尝试与服务端建立连接( connect
)时,由于是io非阻塞的,所以 connect
函数会立即返回,那么如何判断client与server连接成功了呢?
解答
客户端建立连接的示例代码如下:
int res = connect(fd, ...);
if (res < 0 && errno != EINPROGRESS) {
// case1. error, fail somehow, close socket
return;
}
if (res == 0) {
// case2. connection has succeeded immediately
} else {
// case3. connection attempt is in progress
}
由于是非阻塞模式,所以 connect
之后会直接返回,根据返回值 res
和 errno
能够判断建立连接的结果。
- case1,表示连接失败;
- case2,表示连接建立成功;
- case3,表示正在建立连接的过程中,在这个情况下,需要等待socket变成可写(writable)状态,可以使用
select
或epoll
完成;
在 case3 情况下,socket可写后,执行下面的代码检查socket是否出现错误。
- case4和case5,表示socket出现了错误,将会关闭连接;
- case6,表示连接建立成功,可以开始
read
和write
了。
int result;
socklen_t result_len = sizeof(result);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &result, &result_len) < 0) {
// case4. error, fail somehow, close socket
return;
}
if (result != 0) {
// case5. connection failed; error code is in 'result'
return;
}
// case6. socket is ready for read()/write()