Erstellen Sie den Socket mit Socket () und setzen Sie O_Nonblock. Um beschreibbar zu sein < /li>
Sobald der Socket beschreibbar ist, Call Getockopt, um so_error zu erhalten, und der Fehler 0 < /li>
Letztendlich ist die Verbindung nicht bestanden. Enotconn zurück zu Schritt 3. Meine Fragen: < /p>
Ist dieses normale Verhalten des Linux-Kernels oder habe ich einen Fehler gemacht, wie ich mit Epoll oder Nicht-Blocking-Verbindungen umgeht? Eine andere Option wäre, Connect ein zweites Mal aufzurufen und zu prüfen, ob ERRNO ealready oder Eisconn oder einen anderen Fehler ist. Dies ist leistungskritischer Code und der GetPeername () muss in dem gemeinsamen Fall leider auftreten. Ich steuere die beiden Maschinen und das Netzwerk in meiner Umgebung vollständig und weiß, dass jedes TCP-SYN-Segment ein entsprechendes RST-Segment erfüllt wird. Dies ist die gleiche Logik wie der eigentliche Code. Der Hauptunterschied besteht darin, dass der reale Code Co_AWAIT Write_wait (fd) zum Aufsetzen der Coroutine (während in dieser Version es so aussieht, als ob Sie nur synchronous io verwenden sollten, wenn Sie den Thread schlafen, bis die Verbindung erfolgreich ist).
Code: Select all
// Note Errno value initializes tself from the system errno and has a
// conversion operator to std::expected for any T.
std::expected
EventHarness::connect(int fd, const sockaddr *sa, socklen_t len)
{
if (stop_requested())
return Errno{EBADF};
set_nonblock(fd);
set_nodelay(fd);
int err = 0;
write_clear(fd); // Reset detected bit for edge-triggered event
if (::connect(fd, sa, len) == -1)
err = errno;
for (;;) {
if (err == 0)
return {};
if (err != EINPROGRESS) {
reset(fd);
return Errno{err};
}
write_wait(fd); // Go to sleep until fd is writable
write_clear(fd);
len = sizeof(err);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len) == -1)
Errno{}.raise("SO_ERROR");
if (!err) {
sockaddr_storage peer;
len = sizeof(peer);
if (getpeername(fd, reinterpret_cast(&peer), &len) == -1) {
if (errno != ENOTCONN)
Errno{}.raise("getpeername({}): after SO_ERROR 0", fd);
err = EINPROGRESS;
}
}
}
}