?
Solved

Timeout For a Connection

Posted on 2003-11-18
12
Medium Priority
?
1,643 Views
Last Modified: 2007-12-19
Experts,

I am using winsock 2.  Is there a way during a connect() to set it's timeout value or is the timeout based on the network or lan.
0
Comment
Question by:acbirdie
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
12 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 9772071
See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/socket_options_for_windows_nt_and_windows_95_98_me_2.asp ("Socket Options for Windows NT and Windows Me/98/95") on how to do that with WS2:


To set a send time-out, use:

int timeout = TIMEOUT_VALUE;
int err;
SOCKET s;

s = socket( ... );
err = setsockopt(
        s,
        SOL_SOCKET,
        SO_SNDTIMEO,
        (char *)&timeout,
        sizeof(timeout));
if (err != NO_ERROR) {
    /* failed for some reason... */
}
The TIMEOUT_VALUE is the needed time-out in milliseconds. To set a receive time-out, substitute SO_RCVTIMEO for SO_SNDTIMEO in the preceding example.


0
 

Author Comment

by:acbirdie
ID: 9772273
I already know how to do a send timeout.  I am talking about establishing a connection using the connect() command.  I want it to timeout if a connection after a certain amount of time cannot be made.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9773525
Call WSAEventSelect with FD_CONNECT flag. After this call connect - it returns immidiately. Call WSAWaitForMultipleEvents with event from WSAEventSelect specifying required timeout. If WSAWaitForMultipleEvents succeeded, use WSAEnumNetworkEvents to identify what network event occured.

You can see the way implemented in the client application from this article:

http://www.codeproject.com/internet/winsockiocp.asp
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:acbirdie
ID: 9774819
           if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
            {
                  errCode = ERR_SOCK_FAILED;
                  sockErr = WSAGetLastError();
                  break;
            }

      memset(&sServAddr, 0, sizeof(sServAddr));        /* Zero out structure */
            sServAddr.sin_family      = AF_INET;             /* Internet address family */
            sServAddr.sin_addr.s_addr = inet_addr(hostIp);   /* Server IP address */
            sServAddr.sin_port        = htons(hostPort);     /* Server port */

            // Create an even handler
            WSAEVENT WSACreateEvent(void);
            // Connect using primary IP and port number
            if (connect(sock, (struct sockaddr *) &sServAddr, sizeof(sServAddr)) == SOCKET_ERROR)
            {
                  hostIp = cfg_sec_host_serv;
                  convertPort = strtol(cfg_sec_host_port, (char**) NULL, 10);
                  hostPort = convertPort;

                  memset(&sServAddr, 0, sizeof(sServAddr));       /* Zero out structure */
                  sServAddr.sin_family      = AF_INET;            /* Internet address family */
                  sServAddr.sin_addr.s_addr = inet_addr(hostIp);  /* Server IP address */
                  sServAddr.sin_port        = htons(hostPort);    /* Server port */

                  // Connect using second IP and port number
0
 

Author Comment

by:acbirdie
ID: 9774858
AlexFm

Okay, sorry I accidently posted the code without explaining it.  Anyways, ignore the WSAEVENT I was trying to figure out how to do it my self and was getting confused.

Basically I set the address and port info and try to connect. then when the connection fail I try an alternative IP address and port, then I try a third one and give up if cannt connect.  I am a bit confused on how to incorporate your suggestions into my current code.  Can you help me understand.
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 1800 total points
ID: 9776558
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( sock == INVALID_SOCKET )
{
    // error
}

SOCKADDR_IN sServAddr;
// fill sServAddr ...

// connect asynchronously (non-blocking call)
int nRet = connect(sock ,(sockaddr*)&sServAddr, sizeof(sServAddr));

if (nRet == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
{
    // error
}

WSAEVENT hEvent = WSACreateEvent();
if ( hEvent == WSA_INVALID_EVENT )
{
  // error
}

// Ask event notification when socket will be connected
nRet = WSAEventSelect(sock,
        hEvent,
        FD_CONNECT);             // add here another flags for futher processing

if (nRet == SOCKET_ERROR)
{
    // error
}

// wait for connection
DWORD dwRet = WSAWaitForMultipleEvents(1,
            &hEvent ,
            FALSE,
            5000,                     // timeout 5 sec
            FALSE);
   
if (dwRet == WSA_WAIT_TIMEOUT)
{
     // no connection in specified time - add here your handling
}

WSANETWORKEVENTS events;
nRet = WSAEnumNetworkEvents(socket,
            hEvent,
            &events);

if (nRet == SOCKET_ERROR )
{
    // error
}

if ( events.lNetworkEvents & FD_CONNECT )
{
    // connection signaled
    if ( events.iErrorCodes[FD_CONNECT_BIT] != 0 )
    {
        // error
    }

    // connection to server is successful
}

}
0
 

Author Comment

by:acbirdie
ID: 9779859
AlexFM,

I know I will have to do a WSACloseEvent once I am through with everything.  The question I have is do I have to create a new event for each time I attempt to connect to a different IP address if one fails.

acbirdie
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9779940
No, just reset it:

WSAResetEvent(hEvent );
0
 

Author Comment

by:acbirdie
ID: 9781869
I have another question.  Before, once I made a connect I would send something then wait to recv something.  Well now I am not receiving anything.  I get an 10035 error.  When I check the computer that is trying to send something back to me they are saying my socket is closed.  How can I  send and receive info once I establish a connection.

// Set timeout value for receive
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&nTimeout, sizeof(int)) == SOCKET_ERROR)
{
      errCode = ERR_SET_TIME_OUT_FAILED;
      sockErr = WSAGetLastError();
      break;
}
// Send message to server
if ((send(sock, szMessage, strlen(szMessage), 0)) != strlen(szMessage))
{
      errCode = ERR_SEND_FAILED;
      sockErr = WSAGetLastError();
      break;
}

// Attempt to receive message
do
{
      if ((byteRcvd = recv(sock, recvBuffer, 1, 0)) <= 0)
      {
            errCode = ERR_RECV_FAILED;
            sockErr = WSAGetLastError();
            break;
      }
      totalRcvd += byteRcvd;
      os << recvBuffer[0];
} while (recvBuffer[0] != '~');
os << '\0';
            
      
0
 

Author Comment

by:acbirdie
ID: 9782018
Okay,

Well my code works in debug mode but not in release mode.  So I have to figure out what's goin on.  I do have another question.  Does WSACloseEvent take care of WSAWaitForMultipleEvents and WSAEnumNetworkEvents calls too?
0
 

Author Comment

by:acbirdie
ID: 9783316
AlexFM,

Help.  The WSAEWOULDBLOCK is my problem.  I am just allittle confused.  I am able to send the data but not receive it.  What I think is going on is the recv is not ready to get data from the server which is why I am.  If I am right, How can I make sure that the recv and even the send is ready to receive or send data through the socket.  If I am wrong please help me anyways.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9785208
Please read the client project from this article:

http://www.codeproject.com/internet/winsockiocp.asp 

Server project is complicated, but client is relatively simple. It shows how to handle socket events asynchronously, by the same way as it is connected in my code fragment. Any socket call (connect, recv, send...) is by default asynchronous. This means, it returns immidiately with WSAEWOULDBLOCK code. When operation is really completed, event from WSAEventSelect call is signaled. Program waiting for this event in WSAWaitForMultipleEvents wakes up and handles this event.

WSAWOULDBLOCK means: this call would block if socket was blocking. However, socket is non-blocking, function returns immidiately and you should wait for actual completion of socket I/O operation by some way (for example, waiting for event).
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question