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.


Anmelden zum Antworten