问题

使用非阻塞( 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 之后会直接返回,根据返回值 reserrno 能够判断建立连接的结果。

  • case1,表示连接失败;
  • case2,表示连接建立成功;
  • case3,表示正在建立连接的过程中,在这个情况下,需要等待socket变成可写(writable)状态,可以使用 selectepoll 完成;

在 case3 情况下,socket可写后,执行下面的代码检查socket是否出现错误。

  • case4和case5,表示socket出现了错误,将会关闭连接;
  • case6,表示连接建立成功,可以开始 readwrite 了。
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()

参考资料