ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Set timeout for connect socket

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Set timeout for connect socket

    Hello,

    I must get data from a scale by socket. It works fine when the scale is online. If not the program waits without end. I try for several days to set a timeout for connecting to a socket. I tried it in this way but it has no effect. Any ideas how to get it?

    D setsockopt PR 10I 0 ExtProc('qso_setsockopt98')
    D socket_desc 10I 0 Value
    D level 10I 0 Value
    D option_name 10I 0 Value
    D option_value * Value
    D option_length 10I 0 Value

    D p_timeval S *
    d TimeVal DS based(p_timeval)
    d Seconds 10i 0
    d usec 10i 0

    ....

    seconds = 5;
    usec = 0;
    setsockopt(sock
    :SOL_SOCKET
    :SO_RCVTIMEO
    :%addr(Timeval)
    :%size(Timeval)
    );


  • #2
    Hi Hubert,

    Is your socket set to blocking?

    I use this kind of socket, and before set the SO_RCVTIMEO I put the socket to blocking, here my code snippet:

    Code:
    Flags = FCntl( Sck : F_GETFL);                   
    // If socket is blocking ok                      
    If %BitAnd(Flags: O_NONBLOCK) <> 0;              
      dsply = 'Socket is just Blocking.';               
    Else;                                            
      // Tell to socket we want blocking...          
      Flags = %bitand(flags: %bitnot(O_NONBLOCK));   
      If Fcntl( Sck : F_SETFL: flags) < 0;           
        Dsply  'Error set Socket Blocking';
        Return -1;                                   
      EndIf;                                         
      dsply  'Socket is set to Blocking.';
    EndIf;                                                        
    
    // Set timeout to 5 seconds                  
    Tv_Sec = 5;                                                   
    Tv_Usec = 0;                                                  
    
    RC = SetSockOpt(Sck :SOL_SOCKET :SO_RCVTIMEO:             
                      %addr(TimeVal): %size(TimeVal));            
    If RC = -1;                                           
      Dsply 'SetSockOpt TimeOut Socket Recv Error.';  
      // Exctarct error                     
      PErrno = sys_errno();                                       
      Status = %Str(StrError(ErrNo));                  
      Return -1;                                                  
    EndIf;
    Tell me if this help you.
    Bye

    Comment


    • #3
      Hi,

      unfortunately it does'nt. I get this Output:

      Socket is set to Blocking.
      Timeout set to = 2
      Open = 3447 Used time: 188

      When I set the timeout value to 1 I get this output:

      Socket is set to Blocking.
      SetSockOpt TimeOut Socket Recv Error.
      Timeout = 3447

      Even if the scale goes online while the program tries to connect, i get the errors. When it is online it works fine. But I must have car, that the programm does not too long wait when the scale is offline or any error occurrs.

      Comment


      • #4
        That isn't how you check for time out on a socket!!

        The SO_RCVTIMEO (and corresponding SO_SNDTIMEO) socket options are not used by the normal send/recv APIs. To use these, you'd have to use a different set of socket APIs. Also these are only for send/receive and are not for connecting.

        The best approach is do NOT use these.

        The best and most robust approach is to use non-blocking sockets together with the select() or poll() APIs.

        The quicker, but less robust approach, is to use alarm signals together with a blocking socket.

        Comment


        • #5
          Hi Scott,

          in your socket tutorial seems it to use select() for a server application. But I need a client application.
          The situation: some scales are connected by WIFI. In the industrial environment with a lot of steel the WIFI is somtimes malfunctioning. Then the program stops for a long time and the user don't know what happens. I need to make this time shorter in the connect. Is there any possibility to set a timeout for the connect() ?
          Thanks
          Hubert

          Comment


          • #6
            Hubert,

            The process for a client connection works like this:

            1. Create a socket by calling the socket() API
            2. Set the socket to non-blocking with the fcntl() API
            3. Call the connect() API. It's possible that this will succeed and connect you, so be ready for that possibility. However, most of the time it will fail with errno=EINPROGRESS to indicate that the connect() has started, but not finished... it will be connecting in the background due to being a non-blocking socket.
            4. If the connect() was unsuccessful, and you did not get EINPROGRESS, treat it as a normal error
            5. If it was unsuccessful and you did get EINPROGRESS call select() with a timeout, and wait for the socket to be "writable" (or in the writable set). If select() Returns 0 or the descriptor is not in the writable set after select() returns, this tells you that you got a time out.
            6. If you did not get a timeout, it means either there was an error or the connection was successful. The way you tell is by calling the getsockopt() API to retrieve the SO_ERROR socket option. This returns the error code that was set in the background while the connect() was running. If the connection succeeded, this error number will be 0, otherwise it will be the errno-type code for the failure.
            7. If all is well, you are connected and can do the recv/send/etc and remember to use select() because you are in non-blocking mode
            8. If SO_ERROR did report an error, then report the error appropriately to the user/operator/logfile, etc. Then close the socket... you need to create a new socket if you want to try again.

            You can find examples of this in the source code for my HTTPAPI project (which is open source, so the source code is freely available). I imagine you'll find the info elsewhere on the internet as well.

            Good luck

            Comment

            Working...
            X