podido hacer sin bloqueo connect(), asumiendo que el socket ya se ha hecho sin bloqueo:
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
}
Para el segundo caso, en connect() fallado con EINPROGRESS (y sólo en este caso), debe esperar a que el zócalo sea escribible, por ej. para epoll especifica que estás esperando EPOLLOUT en este socket. Una vez que se le notifica que es escribible (con epoll, también esperar para obtener una EPOLLERR o evento EPOLLHUP), comprobar el resultado del intento de conexión:
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()
En mi experiencia, en Linux, connect() Nunca de inmediato tiene éxito y siempre tienes que esperar por la escritura. Sin embargo, por ejemplo, en FreeBSD, he visto no-blocking connect() a localhost tener éxito de inmediato.
Esto podría ayudarle a: http://stackoverflow.com/questions/2875002/non-blocking-tcp-connect-with-epoll –
Como una posible alternativa a las sugerencias en la página vinculada de DJB, me gustaría sugerir tratar de 'dup 'y' cerrar' el descriptor (y usar el duplicado).No probado, pero debería funcionar, según entiendo. Los documentos indican que es un error de programación grave no verificar el valor de retorno de 'cerrar', ya que puede devolver un error anterior. Eso es justo lo que quiere (si 'close' da un error,' connect' falló). Aunque, por supuesto, si usas 'epoll', entonces tienes la garantía de tener un sistema operativo donde' getsockopt (SO_ERROR) 'funcionará ... – Damon
Si es viable, la opción más simple es esperar hasta que connect() regrese antes de configurar NON_BLOCK. – delicateLatticeworkFever