Direct testing is impossible. Determining if a connection is still alive can only be done at the moment of communicating. If you try to send or receive data on a broken TCP channel, then an error is returned. This is the only way to test for a broken TCP channel! There are not any event what can be raised when connection was broken.
If connection is closed gracefully, then CanRead is signalled, but the read operation reads 0 bytes.
Yes, other packages have an 'active' property, but the true value of this property is determined using the previous principles. It is not a direct determination of the live TCP connection status. It is a faked value!
To determinate if FTP connection is still alive you can use that function:
function CheckFtpConnection(AFtpSend: TFtpSend): Boolean; begin if AFtpSend.Sock.Socket = NOT(0) then // Check if socked was ever opened Result := AFtpSend.Login // If not, then connect and login to FTP else if AFtpSend.NoOp then // Send NOOP (No Operation) FTP command to check FTP connection Result := True // If it response without error then connection works fine else Result := AFtpSend.Login; // If fails (for some reasos, timeout, etc), then connect and login to FTP end; //[...] procedure TForm1.Button1Click(Sender: TObject) begin if not CheckFtpConnection(FtpSend) then // Check if connection works fine, if not then it will reconnect as needed begin ShowMessage('Connection to FTP failed!'); Exit; end; // Do FTP action(s) //[...] if FtpSend.List('/', False) then //[...] end;