int_acct
asked on
Socket Error - how to make it appear out fast?
ermz..i have a problem here... i want to connect a server-client application to a wireless LAN device thru sockets. But when the other device is not found, an error 10051 or something like that appears.
Rite now that error appears out after 2 mins or so .I need the error to appear out faster. Is there any way for me to do it?
Rite now that error appears out after 2 mins or so .I need the error to appear out faster. Is there any way for me to do it?
How long does it take if it succeeds? Some seconds?
You could do the following:
- set the socket to non-blocking before connect
- call connect
- the call immediately returns with SOCKET_ERROR and WSAE_WOULDBLOCK
- after that you have to use select function to check whether the socket is
 writeable (connection succeeded) or not.
- the select function may called using an appropriate  timeout  value.
Regards, Alex
You could do the following:
- set the socket to non-blocking before connect
- call connect
- the call immediately returns with SOCKET_ERROR and WSAE_WOULDBLOCK
- after that you have to use select function to check whether the socket is
 writeable (connection succeeded) or not.
- the select function may called using an appropriate  timeout  value.
Regards, Alex
ASKER
ermz...i want it to fail... and i want the failure to come out faster... could i have some sample codes plz? i have totally no idea as to how to how to do it...
 Â
  // set the socket to nonblocking
  unsigned long argp = 1;
  ioctlsocket (socket, FIONBIO, &argp);
  unsigned long ipHost  = inet_addr("192.168.0.1");
  UShort      portNo  = 51239;
  struct sockaddr_in host;
  // fill awsome sockaddr_in structure
  memset (&host, 0, sizeof (host));        // set all zero  Â
  host.sin_family    = AF_INET;          // the only family supported
  host.sin_port     = htons(portNo);      // host order to network order
  host.sin_addr.s_addr = ipHost;         // that is big endian
 Â
  int result = 0;
  // connect to socket fails because of non-blocking socket
  if ((result = connect(sock, (struct sockaddr*) &host, sizeof(host))) < 0)
  {
    // fd_set manages an array of sockets
    fd_set      writeSockets;
    struct timeval  tval;
    // set host socket as first and only element
    FD_ZERO(&writeSockets);
    FD_SET(sockHost, &writeSockets);
    // init timeout
    tval.tv_sec  = 2;  // wait 2 seconds
    tval.tv_usec = 0;
    result = select(sockHost + 1, NULL; &writeSockets, NULL, &tval);
    if (result == 0)
       return 1;  // timeout, the socket was not writeable within timeout
    else if (result == SOCKET_ERROR)
       return 2;  // socket error
   Â
    // if come here the connection succeeded
...
Regards, Alex
ASKER
ermz.... sorry i meant i needed the sample codes for setsockopt() to change the timeouts for send() and recv(). Â sorry sorry...
>>>> ermz....
who is ermz?
>>>>Â i needed the sample codes for setsockopt() to change the timeouts for send() and recv()
changing sending/receiving timeouts doesn't help for connection. The connection timeouts are with your tcp/ip subsystem and must be configured there.
The method I told you above doesn't speed up connection but gives your prog control while the connection is in progress. So, if for example there is no connection after 10 seconds, you may decide that the device isn't available.
Regards, Alex
who is ermz?
>>>>Â i needed the sample codes for setsockopt() to change the timeouts for send() and recv()
changing sending/receiving timeouts doesn't help for connection. The connection timeouts are with your tcp/ip subsystem and must be configured there.
The method I told you above doesn't speed up connection but gives your prog control while the connection is in progress. So, if for example there is no connection after 10 seconds, you may decide that the device isn't available.
Regards, Alex
ASKER
oh ok..sorry abt that Alex... so should i implement this on the server side or the client side? i want the error message to appear on the server side... and where should i implement this? i mean...which part of the server codes should i add this in?
>>>> i want to connect a server-client application to a wireless LAN
If your initial requirement still is valid ... of course it is a client connect. When the server opens, binds and listens to a socket, WLAN isn't involved. The local TCP/IP subsystem should be valid with or without WLAN device, except that the WLAN device works as a DHCP server. In the latter case your system gets a valid IP address from the device, ergo, no device no IP address.
What is the IP address/port your server binds and listens to? It must be the same the clients are using to connect. Is it always valid, could you make a ping on it? Or are you using 127.0.0.1 ?
>>>>Â should i implement this on the server side or the client side?
the code snippet is for a client connect. You can use it to prevent your clients from *hanging* if the WLAN device isn't available or working. By making a socket non-blocking all requests to a socket - connect/recv/accept/discon nect ... immediately return to the caller - it doesn't hang. However, the requests rarely succeed but return with socket error and error code WSAE_WOULDBLOCK, indicating that the call wasn't finished. You either have to poll your request, e. g. recv, or use functions like select() that give information about the status of the socket. If - for example - the connect finally succeeds, the socket status asynchronously turns to writeable. So, if a call to select finds out that the socket is writeable, you know that the inital connect was finished. The benefit of this method is that select can be called with timeout. So, if you want to wait 5 seconds but not more, you can do that by using select.
For the server site the odds are different. A server binds and listens to a server socket. The only dependence on a WLAN device could be if the device acts as DHCP server. But, if the WLAN doesn't work, your server has nothing to serve. So it seems that it doesn't matter whether it hangs on a missing WLAN-Device or not. After listen the server calls accept() in order to accept connecting clients. The accept call is going to hang if the socket is blocking. You can avoid this by setting the socket to non-blocking as described above. Then, you have to poll the socket in order to accept incoming connections. Or you check the read status of your socket using select with timeout. In both cases you keep control of your program and be able to exit, e. g. on user request.
If your server connects to a second server, it is a client for that purpose. So, you may use the code snippet from above tor prevent from hanging.
Regards, Alex
 Â
If your initial requirement still is valid ... of course it is a client connect. When the server opens, binds and listens to a socket, WLAN isn't involved. The local TCP/IP subsystem should be valid with or without WLAN device, except that the WLAN device works as a DHCP server. In the latter case your system gets a valid IP address from the device, ergo, no device no IP address.
What is the IP address/port your server binds and listens to? It must be the same the clients are using to connect. Is it always valid, could you make a ping on it? Or are you using 127.0.0.1 ?
>>>>Â should i implement this on the server side or the client side?
the code snippet is for a client connect. You can use it to prevent your clients from *hanging* if the WLAN device isn't available or working. By making a socket non-blocking all requests to a socket - connect/recv/accept/discon
For the server site the odds are different. A server binds and listens to a server socket. The only dependence on a WLAN device could be if the device acts as DHCP server. But, if the WLAN doesn't work, your server has nothing to serve. So it seems that it doesn't matter whether it hangs on a missing WLAN-Device or not. After listen the server calls accept() in order to accept connecting clients. The accept call is going to hang if the socket is blocking. You can avoid this by setting the socket to non-blocking as described above. Then, you have to poll the socket in order to accept incoming connections. Or you check the read status of your socket using select with timeout. In both cases you keep control of your program and be able to exit, e. g. on user request.
If your server connects to a second server, it is a client for that purpose. So, you may use the code snippet from above tor prevent from hanging.
Regards, Alex
 Â
ASKER
Oh I see...so does that mean that if i use the codes that u have given me, it would result in the socket not being to connect most of the time?
ASKER
These are my codes...how do i do it...
      void servSocket::PrepSend()
      {
          Â
           //      CString ippp = takeoutIP("DoorBellIp");
          Â
           //      char* p = ( LPCTSTR) ippp; //uses CString::operator ( LPCTSTR);
           //char p[16];
           //p = ippp.GetBuffer(0);
          Â
          Â
           // Initialize Winsocket.
           if (WSAStartup (MAKEWORD(1,1), &sendWSAData) != 0)
           {
                 wsprintf (szSendError, TEXT("WSAStartup failed. Error: %d"),
                      WSAGetLastError ());
                 MessageBox (NULL, szSendError,NULL, MB_OK);
           }
          Â
           // Create a TCP/IP socket that is bound to the server.
           if ((ServerSendSock = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
           {
                 wsprintf (szSendError, TEXT("Allocating socket failed. Error: %d"),
                      WSAGetLastError ());
                 MessageBox (NULL, szSendError,NULL, MB_OK);
                Â
           }
          Â
           // Fill out the server socket's address information.
           send_destination_sin.sin_f amily = AF_INET;
          Â
           // Retrieve the host information corresponding to the host name.
           if ((sendPhostent = gethostbyname (HOSTNAME)) == NULL)
           {
                 wsprintf (szSendError, TEXT("Unable to get the host name. Error: %d"),
                      WSAGetLastError ());
                 MessageBox (NULL, szSendError,NULL, MB_OK);
                 closesocket (ServerSendSock);
           }
          Â
           // Assign the socket IP address.
           memcpy ((char FAR *)&(send_destination_sin.s in_addr),
                 sendPhostent->h_addr,
                 sendPhostent->h_length);
          Â
           // Convert to network ordering.
          Â
           send_destination_sin.sin_p ort = htons (PCLISTEN);
          Â
           // Convert into char
           char ipAddr[16];
           int ipLength=0;
           CString m_ServerIP;
          Â
          Â
           m_ServerIP =       "192.168.0.15";
           ipLength = m_ServerIP.GetLength();
           if(ipLength != 0)
           {
                Â
                 for(int i=0;i<ipLength;i++) {
                      ipAddr[i] = (char)m_ServerIP.GetAt(i);
                 }
                 ipAddr[i] = '\0';
           }
           else
           {
                 MessageBox (NULL,_T("Enter IP Address"), NULL,MB_OK);
           }
          Â
           send_destination_sin.sin_a ddr.s_addr = inet_addr(ipAddr);
          Â
           // Establish a connection to the server socket.
           if (connect (ServerSendSock,
                 (PSOCKADDR) &send_destination_sin,
                      sizeof (send_destination_sin)) == SOCKET_ERROR)
           {
                 wsprintf (szSendError,TEXT("Connect ing to the server failed. Error: %d"),
                      WSAGetLastError ());
                 MessageBox (NULL, szSendError + (CString)"\nPlease check if u registered the PDA",NULL, MB_OK);
                 closesocket (ServerSendSock);
           }
          Â
      }
      void servSocket::PrepSend()
      {
          Â
           //      CString ippp = takeoutIP("DoorBellIp");
          Â
           //      char* p = ( LPCTSTR) ippp; //uses CString::operator ( LPCTSTR);
           //char p[16];
           //p = ippp.GetBuffer(0);
          Â
          Â
           // Initialize Winsocket.
           if (WSAStartup (MAKEWORD(1,1), &sendWSAData) != 0)
           {
                 wsprintf (szSendError, TEXT("WSAStartup failed. Error: %d"),
                      WSAGetLastError ());
                 MessageBox (NULL, szSendError,NULL, MB_OK);
           }
          Â
           // Create a TCP/IP socket that is bound to the server.
           if ((ServerSendSock = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
           {
                 wsprintf (szSendError, TEXT("Allocating socket failed. Error: %d"),
                      WSAGetLastError ());
                 MessageBox (NULL, szSendError,NULL, MB_OK);
                Â
           }
          Â
           // Fill out the server socket's address information.
           send_destination_sin.sin_f
          Â
           // Retrieve the host information corresponding to the host name.
           if ((sendPhostent = gethostbyname (HOSTNAME)) == NULL)
           {
                 wsprintf (szSendError, TEXT("Unable to get the host name. Error: %d"),
                      WSAGetLastError ());
                 MessageBox (NULL, szSendError,NULL, MB_OK);
                 closesocket (ServerSendSock);
           }
          Â
           // Assign the socket IP address.
           memcpy ((char FAR *)&(send_destination_sin.s
                 sendPhostent->h_addr,
                 sendPhostent->h_length);
          Â
           // Convert to network ordering.
          Â
           send_destination_sin.sin_p
          Â
           // Convert into char
           char ipAddr[16];
           int ipLength=0;
           CString m_ServerIP;
          Â
          Â
           m_ServerIP =       "192.168.0.15";
           ipLength = m_ServerIP.GetLength();
           if(ipLength != 0)
           {
                Â
                 for(int i=0;i<ipLength;i++) {
                      ipAddr[i] = (char)m_ServerIP.GetAt(i);
                 }
                 ipAddr[i] = '\0';
           }
           else
           {
                 MessageBox (NULL,_T("Enter IP Address"), NULL,MB_OK);
           }
          Â
           send_destination_sin.sin_a
          Â
           // Establish a connection to the server socket.
           if (connect (ServerSendSock,
                 (PSOCKADDR) &send_destination_sin,
                      sizeof (send_destination_sin)) == SOCKET_ERROR)
           {
                 wsprintf (szSendError,TEXT("Connect
                      WSAGetLastError ());
                 MessageBox (NULL, szSendError + (CString)"\nPlease check if u registered the PDA",NULL, MB_OK);
                 closesocket (ServerSendSock);
           }
          Â
      }
>>>> it would result in the socket not being to connect most of the time
No, the result is only, that the connect call returns immediately and you don't have to wait until the connection actually is done.
>>>>Â These are my codes...how do i do it...
You seem to mixup server and client in your code...
By using gethostbyname you normally set-up a server socket that would bind and listen and finally calls accept to be able to accept clients that try to connect to your server. Â However, you actually don't use the information received by gethostbyname but init a new struct host for IP 192.168.0.15 which obviously is a different server. So your program turns to a client and tries to connect to a different server.
BTW, Â the code sequence
     // Convert into char
     char ipAddr[16];
     int ipLength=0;
     CString m_ServerIP;
    Â
    Â
     m_ServerIP =    "192.168.0.15";
     ipLength = m_ServerIP.GetLength();
     if(ipLength != 0)
     {
       Â
        for(int i=0;i<ipLength;i++) {
          ipAddr[i] = (char)m_ServerIP.GetAt(i);
        }
        ipAddr[i] = '\0';
     }
     else
     {
        MessageBox (NULL,_T("Enter IP Address"), NULL,MB_OK);
     }
    Â
can be replaced by that single statement.
  char ipAddr[] = "192.168.0.15";
>>>>Â Where to set the socket to non-blocking?
Directly before the connect. Your code would change to
    // set the socket to nonblocking
    unsigned long argp = 1;
    ioctlsocket (ServerSendSock, FIONBIO, &argp);
     // Establish a connection to the server socket.
     int rc;
     if ((rc = connect (ServerSendSock,
        (PSOCKADDR) &send_destination_sin,
          sizeof (send_destination_sin))) == SOCKET_ERROR)
     {
        unsigned err = WSAGetLastError ();
        if (err != WSAE_WOULDBLOCK)
        {
          wsprintf (szSendError,TEXT("Connect ing to the server failed. Error: %d"),
          WSAGetLastError ());
          MessageBox (NULL, szSendError + (CString)"\nPlease check if u registered the PDA",NULL, MB_OK);
          closesocket (ServerSendSock);
          return;
        }
        // fd_set manages an array of sockets
        fd_set      writeSockets;
        struct timeval  tval;
        // set host socket as first and only element
        FD_ZERO(&writeSockets);
        FD_SET(ServerSendSock, &writeSockets);
        // init timeout
        tval.tv_sec  = 2;  // wait 2 seconds
        tval.tv_usec = 0;
        result = select(ServerSendSock + 1, NULL; &writeSockets, NULL, &tval);
        if (result == 0)
        {
            MessageBox (NULL, szSendError + (CString)"\nConnection failled to succeed within timeout.",NULL, MB_OK);
            return;  // timeout, the socket was not writeable within timeout
        }
        else if (result == SOCKET_ERROR)
        {
            wsprintf (szSendError,TEXT("Connect ing to the server failed. Error: %d"),
            WSAGetLastError ());
            MessageBox (NULL, szSendError + (CString)"\nPlease check if u registered the PDA",NULL, MB_OK);
            closesocket (ServerSendSock);
            return;  // socket error
         }
         // if come here the connection succeeded
     }
    Â
   }
Regards, Alex
No, the result is only, that the connect call returns immediately and you don't have to wait until the connection actually is done.
>>>>Â These are my codes...how do i do it...
You seem to mixup server and client in your code...
By using gethostbyname you normally set-up a server socket that would bind and listen and finally calls accept to be able to accept clients that try to connect to your server. Â However, you actually don't use the information received by gethostbyname but init a new struct host for IP 192.168.0.15 which obviously is a different server. So your program turns to a client and tries to connect to a different server.
BTW, Â the code sequence
     // Convert into char
     char ipAddr[16];
     int ipLength=0;
     CString m_ServerIP;
    Â
    Â
     m_ServerIP =    "192.168.0.15";
     ipLength = m_ServerIP.GetLength();
     if(ipLength != 0)
     {
       Â
        for(int i=0;i<ipLength;i++) {
          ipAddr[i] = (char)m_ServerIP.GetAt(i);
        }
        ipAddr[i] = '\0';
     }
     else
     {
        MessageBox (NULL,_T("Enter IP Address"), NULL,MB_OK);
     }
    Â
can be replaced by that single statement.
  char ipAddr[] = "192.168.0.15";
>>>>Â Where to set the socket to non-blocking?
Directly before the connect. Your code would change to
    // set the socket to nonblocking
    unsigned long argp = 1;
    ioctlsocket (ServerSendSock, FIONBIO, &argp);
     // Establish a connection to the server socket.
     int rc;
     if ((rc = connect (ServerSendSock,
        (PSOCKADDR) &send_destination_sin,
          sizeof (send_destination_sin))) == SOCKET_ERROR)
     {
        unsigned err = WSAGetLastError ();
        if (err != WSAE_WOULDBLOCK)
        {
          wsprintf (szSendError,TEXT("Connect
          WSAGetLastError ());
          MessageBox (NULL, szSendError + (CString)"\nPlease check if u registered the PDA",NULL, MB_OK);
          closesocket (ServerSendSock);
          return;
        }
        // fd_set manages an array of sockets
        fd_set      writeSockets;
        struct timeval  tval;
        // set host socket as first and only element
        FD_ZERO(&writeSockets);
        FD_SET(ServerSendSock, &writeSockets);
        // init timeout
        tval.tv_sec  = 2;  // wait 2 seconds
        tval.tv_usec = 0;
        result = select(ServerSendSock + 1, NULL; &writeSockets, NULL, &tval);
        if (result == 0)
        {
            MessageBox (NULL, szSendError + (CString)"\nConnection failled to succeed within timeout.",NULL, MB_OK);
            return;  // timeout, the socket was not writeable within timeout
        }
        else if (result == SOCKET_ERROR)
        {
            wsprintf (szSendError,TEXT("Connect
            WSAGetLastError ());
            MessageBox (NULL, szSendError + (CString)"\nPlease check if u registered the PDA",NULL, MB_OK);
            closesocket (ServerSendSock);
            return;  // socket error
         }
         // if come here the connection succeeded
     }
    Â
   }
Regards, Alex
ASKER
It says that WASE_NONBLOCKING : undeclared error...
ASKER
and result undeclared indentified error too...
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
Refer: http://tangentsoft.net/wskfaq/newbie.html#timeout
_novi_