To do a non-blocking connect(), assuming the socket has already been made non-blocking:
int res = connect(fd, ...);
if (res < 0 && errno != EINPROGRESS) {
// error, fail somehow, close socket
return;
}
if (res == 0) {
// connection has succeeded immediately
} else {
// connection attempt is in progress
}
For the second case, where connect() failed with EINPROGRESS (and only in this case), you have to wait for the socket to be writable, e.g. for epoll specify that you're waiting for EPOLLOUT on this socket. Once you get notified that it's writable (with epoll, also expect to get an EPOLLERR or EPOLLHUP event), check the result of the connection attempt:
int result;
socklen_t result_len = sizeof(result);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &result, &result_len) < 0) {
// error, fail somehow, close socket
return;
}
if (result != 0) {
// connection failed; error code is in 'result'
return;
}
// socket is ready for read()/write()
In my experience, on Linux, connect() never immediately succeeds and you always have to wait for writability. However, for example, on FreeBSD, I've seen non-blocking connect() to localhost succeeding right away.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…