Attempts to establish client connections (TCPOP_CONNECT) are generally quick to succeed or fail, unlike listening for connections from the server side, which might involve an indefinite wait. Still, in some cases such as slow DNS servers, sneaky firewalls, many hops, routing problems, etc., it can take several seconds to determine whether the connection can be made, during which your application is effectively hung. You can put a limit on the wait by specifying a timer value, but that only gives you the ability to abort the connection if the attempt takes too long. If you're willing to allow the connection attempt to take several seconds, but don't want to be stuck while waiting, you can make an asynchronous client connection request, with the following procedure. (This capability added in edit 996.3).
Start by calling TCPX with the TCPOP_CONNECT opcode, but also specify the TCPXFLG_ASYNC option in flags. TCPXFLG_BLOCK is optional. You can set timer > 0 if you're willing to wait a short time to allow a successful connection to be fully established, but don't want to abort the connection if it takes longer than the limit. Otherwise, with timer = 0, the call will always return immediately. The only point of setting timer to, say 1 second, would be to possibly eliminate the need for the following TCPOP_CHECK calls if the connection succeeds quickly.
If the connection succeeds immediately, or within the limit set by timer, it will return status = 1, and the connected socket in sockport. This case is identical to the normal, synchronous, connection, except that the return status is 1 instead of 0, and from this point forward, it can be handled just like a normal connected socket.
Similarly, if the connection fails immediately or within the limit set by timer, it will return status < 0.
Otherwise, it will return status = 0 (indicating "pending") and yet it will return the open (or "half open") socket in sockport. In this case, you are free to do other things while waiting for the connection attempt to finally succeed or fail. To check on the progress of the operation, you must use TCPOP_CHECK with the half open sockport, also specifying TCPXFLG_ASYNC, and optionally, TCPXFLG_BLOCK. This will return status =0 to indicate that the connection attempt is still pending, 1 to indicate a successful completed connection, or <0 to indicate a failed connection, in which case the socket will be closed for you. If and when the connection succeeds, you can the treat it like a normal client socket.
Notes:
• | If you want a blocking connection, you need to specify TCPXFLG_BLOCK both in the TCPOP_CONNECT call and in the TCPOP_CHECK call(s), since the blocking status cannot be set until after the connection is finally complete. |
• | If you get tired of waiting for the connection to complete, you can call TCPOP_CLOSE at any time to terminate it. This might be useful, for example, if you were to display a dialog box saying "Attempting connection…" which gave the user a CANCEL button option. |
• | You can do other work while waiting for a connection to succeed or fail by specifying the TCPXFLG_ASYNC flag with the TCPOP_CONNECT operation. In that case, if the connection cannot be established within the time limit specified by TIMER (or immediately, if TIMER=0), then the subroutine returns with STATUS=0 and SOCKPORT (>0) set to the socket whose connection attempt is still in progress. (You can consider this socket "half opened", meaning it is open on your end, but the other end still hasn't responded.) You must then use TCPOP_CHECK (continuing to specify the TCPXFLG_ASYNC flag and the half-opened socket in SOCKPORT) to check whether the connection attempt is complete. STATUS=1 indicates success, STATUS<0 indicates an error, STATUS=0 indicates that the connection attempt is still pending. |