[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: socket connect timeout



Sender: Scott Klement <sk@xxxxxxxxxxxxxxxx>

Hello,

c                   eval      sock = socket(AF_INET: SOCK_STREAM:
c                                           IPPROTO_IP)
c                   if        sock < 0
c                   eval      msg = 'Error calling socket()!'
c                   dsply                   msg
c                   return
c                   endif


I'm sorry -- but this is very poorly done. You need to tell the user what went wrong, not which API failed. When a socket can't be created, is it because TCP/IP isn't installed? Is it because the user doesn't have enough authority? Whne a connect() attempt fails, is it because the host refused the connection? Or because it timed out? Or because the network is down?

You need to provide useful error messages. "socket() failed" or "connect() failed" are not useful.

If this is code that you're intending to submit to the FTPAPI project, I'll have to reject it if it doesn't provide useful error messages.


c                   Eval      $connect = false
c     1             Do        10
c                   Eval      RC = connect(sock: p_connto: addrlen)
c                   If        RC < 0
*c                   eval      msg = 'Not connected...'
*c                   dsply                   msg
C                   call      'DELAY'
C                   Else
c                   Eval      $connect = true
c                   eval      msg = 'Connected!'
c                   dsply                   msg
C                   leave
C                   endif
c                   Enddo

After the above loop I still have a RC that is -1. Any ideas?

Yes... Here's what happens:


a) You call connect() the first time. Something may be wrong that the host isn't available or you provided bad parameters, or whatever. In that case connect() returns -1 to tell you about the error. If nothing is wrong, the connect will be "started" but will complete in the background because you're in non-blocking mode. When it's started, it'll return -1 and errno will be EINPROGRESS to tell you that it's working on it. In either case, you'll always get a -1 from connect().

b) The next time you call connect() will depend on what your first problem was. If the first time was an error, and the connection is not in progress, then it'll try to do the same thing as before and produce the same error. If it first time was successful and the connection attempt is either in progress or completed, then you'll get an error saying that it's in progress or that it's already connected.

Consequently, you'll always get a -1.

The solution to your problems are:

a) ALWAYS ALWAYS ALWAYS check errno to find out what went wrong. Only continue the connection progress if the error is EINPROGRESS. Don't use the -1 by itself.

b) Use the select() API to wait until the socket is writable. Once it's writable, you'll know that the connection has been completed. Get used to using the select() API, since non-blocking sockets are pretty much useless without it.

c) Once the socket is writable, you might be connected, or you might have an error. When you try to use send() or recv() you'll get an error message if the connection failed. Check for that.

d) Consider using signals to implement your timeout, and only switching to nonblocking mode AFTER the connection is complete. I've found that this greatly simplifies the code, and makes it easier to do proper error reporting. Non-blocking connects are not fun.
-----------------------------------------------------------------------
This is the FTPAPI mailing list. To unsubsribe from the list send mail
to majordomo@xxxxxxxxxxxxx with the body: unsubscribe ftpapi mymailaddr
-----------------------------------------------------------------------