Thread: connect timeout

  1. #1
    Registered User
    Join Date
    Aug 2003
    Posts
    288

    connect timeout

    i finished a program that just requests http pages from the internet and saves them to file (kind of like an offline viewer). anyway, ive noticed that sometimes, it would freeze for about 10 to 20 seconds, after further checking, i found out its caused by connect() and the webserver either cant/doesnt respond.

    i looked up connect timeout on google, and found this method:

    Winsock API functions such as 'send()', 'recv()', 'connect()' etc. block because we are using blocking sockets. The next solution is to simply use non-blocking sockets instead. For a non-blocking socket, 'connect()' returns with 'WSAEWOULDBLOCK' error. However, the connection process goes on. Thus, one crude but simple way of adding a timeout is to issue a 'connect()' call and wait for a specified amount of time, then call a winsock function like 'getpeername()' or 'recv()' that needs a connected socket. If the error is 'WSAENOTCONN' we can safely assume that the socket is not connected and close the socket. The drawback of this method is that even if the connection occurs quickly, it will only be known after the specified timeout. We can reduce this effect by checking at intervals and abandoning the effort once the total time has elapsed.
    heres how i implemented it:

    Code:
    SOCKET serverSocket = WSASocket(AF_INET,
    							SOCK_STREAM,
    							IPPROTO_TCP,
    							NULL,
    							0,
    							WSA_FLAG_OVERLAPPED);
    
    if (connect(serverSocket, (sockaddr *)&addrServer, sizeof(addrServer)) != 0)
    {
    	if (WSAGetLastError() != WSAEWOULDBLOCK)
    		return INVALID_SOCKET;
    
    	struct sockaddr addrTemp = {0};
    	int lenTemp = sizeof(addrTemp);
    	unsigned int nStart = GetTickCount(), nTimeout = 5000;
    
    	while (true)
    	{
    		if (getpeername(serverSocket, &addrTemp, &lenTemp) != 0)
    		{
    			if (WSAGetLastError() == WSAENOTCONN)
    			{
    				if (GetTickCount() > (nStart + nTimeout)) //connect timeout
    					return INVALID_SOCKET;
    			}
    		}
    		else
    		{
    			break;
    		}
    
    		Sleep(200); //check 5 times per second
    	}
    }
    when i do that, it doesnt time out after 5 seconds (like i set).. instead it times out after around 20 seconds with WSAETIMEDOUT.

    i use getpeername() to check if the socket is connected.

  2. #2
    Registered User eth0's Avatar
    Join Date
    Dec 2003
    Posts
    164
    You can't set a timeout like that. You need to readup on the select() function.

    Here's a snippet out of some code I was writing last night.

    Code:
        TIMEVAL timeVal;
        FD_SET readFDS;
        int iSockRet, iSelRet;
    
        /* monitor for incomming connections */
        FD_ZERO(&readFDS);
        FD_SET(icmpSock, &readFDS);
        
        /* set timeout values */
        timeVal.tv_sec  = iTimeOut / 1000;
        timeVal.tv_usec = iTimeOut % 1000;
        
        iSelRet = select(0, &readFDS, NULL, NULL, &timeVal);
        
        if ((iSelRet != SOCKET_ERROR) && (iSelRet != 0)) {
            iSockRet = recvfrom(icmpSock,              //socket
                               (char *)&recvpacket,    //buffer
                               iPacketSize,            //size of buffer
                               0,                      //flags
                               (SOCKADDR *)&source,    //source address
                               &iFromLen);              //pointer to address length
        /* if socket timed out */                             
        } else if (iSelRet == 0) {
            printf("timeout\n");
        } else if (iSelRet == SOCKET_ERROR) {
            printf("select() failed : %d\n", WSAGetLastError());
        }
    Open source isn't a matter of life or death......
    .......its much more important than that!!


    SuSE Linux - GCC 3.4.2
    XP Pro - Visual Studio 2005 TS, MinGW 3.4.2

  3. #3
    Registered User
    Join Date
    Aug 2003
    Posts
    288
    ok so i read through the documentation, and basically, i need to pass a FD_SET to the write param of the select function. and if it returns 0 it timed out, SOCKET_ERROR it failed, otherwise it connected?

    EDIT:

    when do i call select? after or before connect()?

    if its after, connect is blocking so even if i call if after it doesnt do anything.

    do i need to connect nonblocking? and if so how?

    thanks again
    Last edited by X PaYnE X; 05-14-2005 at 03:05 AM.

  4. #4
    Registered User eth0's Avatar
    Join Date
    Dec 2003
    Posts
    164
    Rather than me trying to explain it all, here is a link which will do it much better. http://www.ecst.csuchico.edu/%7Ebeej.../advanced.html
    In fact this whole document is nice and worth a read for anyone new to network programming.

    There are a few examples on that page which you should be able to relate to what you want.
    (note, where it mentions 'STDIN+1' in select, this can be set to 0 in Windows as it isn't used. It's only in the windows decleration for *nix compatability.)

    If your still struggling after reading through this, post the code you have so far.
    Last edited by eth0; 05-14-2005 at 04:32 AM.
    Open source isn't a matter of life or death......
    .......its much more important than that!!


    SuSE Linux - GCC 3.4.2
    XP Pro - Visual Studio 2005 TS, MinGW 3.4.2

  5. #5
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You'll find some useful information and code by doing a search for "connect timeout" on this forum.

  6. #6
    Registered User
    Join Date
    Aug 2003
    Posts
    288
    anonytmous, ur link gives me 'Sorry - no matches. Please try some different terms.' <- useful info

    and i already searched the forums, i could only find info related to recv timeouts (i didnt read ALL the topics, but that was what i generally got)

  7. #7
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You could do the search again (it must have expired, the vBulletin search system is awful, which is why I posted the search terms) or just read these threads:

    http://cboard.cprogramming.com/showt...onnect+timeout
    http://cboard.cprogramming.com/showt...onnect+timeout
    http://cboard.cprogramming.com/showt...onnect+timeout

  8. #8
    Registered User
    Join Date
    Aug 2003
    Posts
    288
    fcntl(sock, F_SETFL, O_NONBLOCK);

    gets mentioned alot, but its not implemented on winsock? its the function i was looking for.

  9. #9
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    MSDN: ioctlsocket
    Code:
    //-------------------------
    // Set the socket I/O mode: In this case FIONBIO
    // enables or disables the blocking mode for the 
    // socket based on the numerical value of iMode.
    // If iMode = 0, blocking is enabled; 
    // If iMode != 0, non-blocking mode is enabled.
    int iMode = 0;
    ioctlsocket(m_socket, FIONBIO, (u_long FAR*) &iMode);

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Non-blocking connect()?
    By pobri19 in forum Networking/Device Communication
    Replies: 9
    Last Post: 04-22-2009, 03:40 PM
  2. Replies: 8
    Last Post: 03-10-2008, 11:57 AM
  3. connect( ) timeout
    By XSquared in forum Networking/Device Communication
    Replies: 2
    Last Post: 03-07-2004, 05:45 PM
  4. Client timed-out once on connect(), can never connect() again
    By registering in forum Networking/Device Communication
    Replies: 6
    Last Post: 10-28-2003, 03:46 PM
  5. Linux cannot connect to internet
    By taps in forum Linux Programming
    Replies: 3
    Last Post: 11-09-2001, 09:11 AM