Solved

Timeout For a Connection

Posted on 2003-11-18
12
1,635 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 450 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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

705 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