Timeout For a Connection

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.
acbirdieAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
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
acbirdieAuthor Commented:
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
AlexFMCommented:
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
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

acbirdieAuthor Commented:
           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
acbirdieAuthor Commented:
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
AlexFMCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
acbirdieAuthor Commented:
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
AlexFMCommented:
No, just reset it:

WSAResetEvent(hEvent );
0
acbirdieAuthor Commented:
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
acbirdieAuthor Commented:
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
acbirdieAuthor Commented:
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
AlexFMCommented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.