R
Hier die mit getsockopt() verbesserte connectTo()-Methode, die bei mir funktioniert:
int InetClientSocket::connectTo() const
{
int iRet = -1;
int res;
int flags;
// set socket non-blocking
if( (flags = fcntl(m_fdSocket, F_GETFL, 0)) < 0 )
exit(-1);
flags |= O_NONBLOCK;
if( fcntl(m_fdSocket, F_SETFL, flags) < 0 )
exit(-1);
do
{
errno = 0;
res = connect(m_fdSocket, (struct sockaddr*)&m_destAddr, sizeof(struct sockaddr_in)) ;
}
while( EINTR == errno );
if(res < 0)
{
if(EINPROGRESS == errno)
{
struct timeval timeout = m_ConnectTimeout;
fd_set wfds; // write file descr set
FD_ZERO(&wfds); // Watch m_fdSocket
FD_SET(m_fdSocket, &wfds);
do
{
errno = 0;
res = select(m_fdSocket+1, NULL, &wfds, NULL, &timeout);
}
while( EINTR == errno );
if(FD_ISSET(m_fdSocket, &wfds)) // socket selected for write // connection successful
{
// hier landet man offenbar IMMER, auch wenn kein Rechner oder LISTEN-Port erreichbar ist
// Socket mit "getsockopt()" pruefen! siehe "man 2 connect"
int so_err;
socklen_t lon = sizeof(so_err);
res = getsockopt(m_fdSocket, SOL_SOCKET, SO_ERROR, (void*)(&so_err), &lon);
if(res < 0) // error
exit(-1);
else // check so_err
{
if(so_err == 0) // success
iRet = 0;
else
exit(-1);
}
}
else
exit(-1);
}
else // (errno != EINPROGRESS) -> connect didn't work
exit(-1);
}
// set socket blocking again
flags &= ~O_NONBLOCK;
if( fcntl(m_fdSocket, F_SETFL, flags) < 0 )
cout << "error" << endl;
return iRet;
}
Viel Spaß damit, Stephan