Per fare un non-bloccante connect(), assumendo la presa è già stato reso non bloccante:
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
}
Per il secondo caso, in cui connect() non riuscita con EINPROGRESS (e solo in questo caso), devi aspettare che il socket sia scrivibile, ad es per epoll specificare che stai aspettando EPOLLOUT su questo socket. Una volta ci si notifica che è scrivibile (con epoll, anche si aspettano di ottenere un EPOLLERR o eventi EPOLLHUP), controllare il risultato del tentativo di connessione:
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()
Nella mia esperienza, su Linux, connect() mai immediatamente ha successo e devi sempre aspettare la scrittura. Tuttavia, per esempio, su FreeBSD, ho visto subito il collegamento non bloccante connect() a localhost.
fonte
2012-04-17 16:07:10
Questo potrebbe aiutare: http://stackoverflow.com/questions/2875002/non-blocking-tcp-connect-with-epoll –
Come possibile alternativa ai suggerimenti sulla pagina DJB collegata, mi piacerebbe suggerire di provare a 'dup 'e' chiudi' il descrittore (e usa il duplicato).Non testato, ma dovrebbe funzionare, a mio modo di vedere. I documenti affermano che è un grave errore di programmazione non controllare il valore restituito di 'close', perché potrebbe restituire un errore precedente. Questo è proprio quello che vuoi (se 'close' dà un errore,' connect' non è riuscito). Anche se si utilizza 'epoll', si ha sicuramente un sistema operativo in cui' getsockopt (SO_ERROR) 'funzionerà ... – Damon
Se possibile, l'opzione più semplice è attendere fino a quando connect() ritorna prima di impostare NON_BLOCK. – delicateLatticeworkFever