ein blockierungs connect() zu tun, die Buchse ist unter der Annahme, bereits nicht blockierend vorgenommen:
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
}
Für den zweiten Fall, wo connect() mit EINPROGRESS fehlgeschlagen (und nur in diesem Fall), müssen Sie warten, bis der Socket beschreibbar ist, z Für epoll geben Sie an, dass Sie auf diesen Socket auf EPOLLOUT warten. Sobald Sie benachrichtigen, dass es beschreibbar ist (mit epoll, auch erwarten ein EPOLLERR oder EPOLLHUP Ereignis zu erhalten), das Ergebnis des Verbindungsversuches überprüfen:
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()
Nach meiner Erfahrung auf Linux, connect() nie ist sofort erfolgreich und Sie müssen immer auf Schreibbarkeit warten. Unter FreeBSD habe ich jedoch festgestellt, dass non-blocking connect() zu localhost sofort erfolgreich ist.
Dies könnte Ihnen helfen: http://stackoverflow.com/questions/2875002/non-blocking-tcp-connect-with-epoll –
Als mögliche Alternative zu den Vorschlägen auf der verlinkten DJB Seite, würde Ich mag zu 'dup vorschlagen versuchen 'und' schließen' Sie den Deskriptor (und verwenden Sie das Duplikat).Nicht getestet, aber es sollte funktionieren, in meinem Verständnis. Die Dokumentation gibt an, dass es ein schwerwiegender Programmierfehler ist, den Rückgabewert von 'close' nicht zu überprüfen, da ein vorheriger Fehler zurückgegeben werden kann. Das ist genau das, was Sie wollen (wenn 'close' einen Fehler ergibt, ist' connect' fehlgeschlagen). Aber natürlich, wenn Sie 'epoll' verwenden, dann haben Sie garantiert ein Betriebssystem, wo' getsockopt (SO_ERROR) 'einfach funktioniert ... – Damon
Wenn möglich, ist die einfachste Option zu warten, bis connect() zurückkehrt, bevor Sie setzen NON_BLOCK. – delicateLatticeworkFever