connect () mit Timeout liefert bei getsockopt falschen Status-Code
-
Hi!
Ich hab mir grade ein connect () auf einem nicht-blockierenden Socket mit select () zusammengebaut:
void Socket::wait (bool read) { fd_set fds; FD_ZERO (&fds); FD_SET (mSocket, &fds); struct timeval tv = { mTimeout, 0 }; int rc = select (mSocket + 1, read ? &fds : NULL, !read ? &fds : NULL, NULL, mTimeout ? &tv : NULL); if (!rc) throw TimeoutException (); else if (rc < 0 || !FD_ISSET (mSocket, &fds)) throw SocketException (); }
void Socket::connect (string host, uint16_t port) { struct sockaddr_in addr; // is the given host already an IP? if (!inet_aton (host.c_str (), &addr.sin_addr)) { // resolv the hostname struct hostent *h = gethostbyname (host.c_str ()); if (!h) throw ResolvException (); addr.sin_addr = *(struct in_addr*) h->h_addr; } addr.sin_port = htons (port); addr.sin_family = AF_INET; int flags; if (mTimeout) { // set to non-blocking mode flags = fcntl (mSocket, F_GETFL); flags |= O_NONBLOCK; fcntl (mSocket, F_SETFL, flags); } // connect if (::connect (mSocket, (struct sockaddr*) &addr, sizeof (addr)) == -1) { if (errno != EINPROGRESS) throw SocketException (); // wait for the connection to establish wait (false); // check if everything went OK int rc; socklen_t rc_len; if (getsockopt (mSocket, SOL_SOCKET, SO_ERROR, &rc, &rc_len) == -1) throw SocketException (); if (rc) throw Exception (rc, strerror (rc)); } if (mTimeout) { // set back to blocking mode flags &= ~O_NONBLOCK; fcntl (mSocket, F_SETFL, flags); } }
Wenn mTimeout jetzt auf etwas anderem als 0 steht bekomm ich mit folgendes Ergebnis (Exception wird in Zeile 45 geworfen und zeigt im Endeffekt errno und strerror (errno) an):
Unknown error 3086596719 (-1208370577)
Wobei sich diese Error-Codes jedes mal ändern.
Wenn ich aber die Zeilen 40 bis 45 mit folgenden Code ersetze, funktioniert die Sache wunderbar (ist aber unsäuberer würd ich meinen):
if (::connect (mSocket, (struct sockaddr*) &addr, sizeof (addr)) == -1 && errno != EALREADY) throw SocketException ();
Was mach ich bei der Variante mit getsockopt () falsch?
-
rc_len enthältbeim Aufruf nicht die Größe von rc.
-
Argh... danke.