fpConnect relies on the underlying OS' socket implementation, which unfortunately for connect, has no timeout control at least on Windows and Linux.
You can set the overal tcp timeout but I would advise against it as it is a global option.
In order to control the timeout for a connect you need to use a socket in non blocking mode (it is using blocking mode by default). You can set the socket in non blocking mode with ioctl and use select to check for the timeout.
In my experience there is no universally-correct answer to this, since the local computer doesn't cache the "up" state of its neighbours- at least as far as pure IP-based protocols are concerned. If the target machine is up it might respond to a request immediately, or there again it might not if there's a tarpit or a port-knocking filter installed.
You could start off by pinging the target, but depending on your local OS you might find you need elevated privilege to do that under program control. But again, many systems disable their ICMP Echo (i.e. "Ping") response.
You can modify most of the Berkeley Sockets API using setsockopt() or, in extremis, select(). I can't find a recent example in my code of doing that to fpListen(), but by analogy and possibly as a useful starting point for experimentation:
if IsBlocking in blocking then begin
timeout.tv_sec := 0; (* Treat this as a blocking call *)
timeout.tv_usec := 0
end else begin
timeout.tv_sec := 0; (* Treat this as a non-blocking call *)
timeout.tv_usec := 10000 (* with this timeout in uSec. *)
end;
if fpSetSockOpt(fSocket, SOL_SOCKET, SO_RCVTIMEO, @timeout, SizeOf(timeout)) < 0 then begin
{$if declared(StrError) }
WriteLn(stderr, 'SetSockopt error ' + IntToStr(SocketError) + ': ' + StrError(SocketError))
{$endif declared }
end;
sockLen := SizeOf(sockAddr);
fClient := fpAccept(fSocket, @sockAddr, @sockLen); (* See timeout above *)
if (fClient < 0) and not (IsBlocking in blocking) then
exit(false); (* No incoming connection, return no character *)
MarkMLl