Setting timeout when using connect () in C ++
I am using sockets in C ++ on linux to connect to a server using connect (), but it has no timeout value. What would be the easiest / best way to pause it for a few seconds. I'll post the code I have and include a blocking connect () call in it:
using namespace std;
int main( int argc, char* argv[] )
{
// Interpret the command line arguments
string uri_string = "";
if ( argc != 2 )
{
cerr << "Usage: " << argv[0];
cerr << " <URI>" << endl;
return 1;
}
else
{
uri_string = argv[1];
}
// Create URI object and have it parse the uri_string
URI *uri = URI::Parse(uri_string);
if ( uri == NULL )
{
cerr << "Error: Cannot parse URI." << endl;
return 2;
}
// Check the port number specified, if none use port 80
unsigned port = 80;
if ( uri->Is_port_defined() )
{
port = uri->Get_port();
}
// Create TCP socket and connect to server
int tcp_sock = socket( AF_INET, SOCK_STREAM, 0 );
if ( tcp_sock < 0 )
{
cerr << "Unable to create TCP socket." << endl;
return 3;
}
sockaddr_in server;
socklen_t slen = sizeof(server);
server.sin_family = AF_INET;
server.sin_port = htons( port );
cout << "Resolving " << uri->Get_host() << "... ";
hostent *hostp = gethostbyname( uri->Get_host().c_str() );
memcpy( &server.sin_addr, hostp->h_addr, hostp->h_length );
struct in_addr **pptr;
pptr = (struct in_addr **)hostp->h_addr_list;
string ip_addr = "";
while( *pptr != NULL ) {
ip_addr += inet_ntoa(**(pptr++));
}
cout << ip_addr << endl;
cout << "Connecting to " << uri->Get_host() << "|" << ip_addr << "|:";
cout << port << "... ";
if ( connect( tcp_sock, (sockaddr*)&server, slen ) < 0 )
{
cerr << "Unable to connect to server via TCP." << endl;
close( tcp_sock );
return 4;
}
cout << "connected." << endl;
// rest of code
}
source to share
Make the socket a non-blocking socket and then use select () or poll () with a timeout value to test writeability. If the select () function returns with a timeout, you haven't connected over time and you can close the socket and deal with the connection failure. If it returns with completion, everything is fine and you can continue.
source to share
Take a look at this newsgroup post for details and sample code on how to timeout socket connections in Lunux. The basic idea is to use non-blocking sockets and then wait for a connection.
source to share
Another way to make non-blocking pain-free select () is to check GetLastError () for EWOULDBLOCK.
// set socket as nonblocking
unsigned long value = 1;
if (ioctlsocket(yourSocket, FIONBIO, &value) == SOCKET_ERROR)
return SOCKET_ERROR;
// (call connect here)
// check if connect would block
if (GetLastError() == EWOULDBLOCK)
return TIMEOUT;
source to share