Pascal (Lazarus/Delphi)
Pascal (Lazarus/Delphi)
FTP Active vs. Passive Data Connections
See more FTP Examples
Demonstrates the data-connection-mode properties Passive, UseEpsv, AutoSetUseEpsv, PassiveUseHostAddr, and the active-mode properties ActivePortRangeStart, ActivePortRangeEnd, and ForcePortIpAddress.
Background: FTP's split into a control connection and separate data connections is the source of most of its firewall trouble. In passive mode (the default, and usually correct) the client opens the data connection, which works through client-side NAT. In active mode the server connects back, requiring the client to be reachable — hence the port-range and advertised-IP settings for opening firewall holes.
EPSV is the IPv6-friendly modern form of passive with automatic PASV fallback, and PassiveUseHostAddr ignores a private IP a misconfigured server may report.Chilkat Pascal (Lazarus/Delphi) Downloads
program ChilkatDemo;
// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.
{$IFDEF FPC}
{$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
SysUtils,
CkDllLoader,
Chilkat.Ftp2;
// ---------------------------------------------------------------------------
procedure RunDemo;
var
success: Boolean;
ftp: TFtp2;
begin
success := False;
ftp := TFtp2.Create;
ftp.Hostname := 'ftp.example.com';
ftp.Username := 'myFtpLogin';
// Passive mode (the default) has the client connect to the server for each data transfer, which
// works through most client-side firewalls. Active mode has the server connect back to the
// client.
ftp.Passive := True;
// In passive mode, optionally use EPSV before falling back to PASV. AutoSetUseEpsv lets Chilkat
// decide automatically.
ftp.UseEpsv := True;
ftp.AutoSetUseEpsv := True;
// PassiveUseHostAddr (default True) uses the control-connection host address rather than the
// address returned by PASV, which avoids problems when a server reports a private IP.
ftp.PassiveUseHostAddr := True;
// The following apply only in ACTIVE mode (Passive = False): restrict the local port range the
// client listens on, and set the IP advertised to the server.
ftp.ActivePortRangeStart := 50000;
ftp.ActivePortRangeEnd := 50100;
ftp.ForcePortIpAddress := '203.0.113.5';
// Normally you would not hard-code the password in source. You should instead obtain it
// from an interactive prompt, environment variable, or a secrets vault.
ftp.Password := 'myPassword';
success := ftp.Connect();
if (success = False) then
begin
WriteLn(ftp.LastErrorText);
Exit;
end;
WriteLn('Connected.');
success := ftp.Disconnect();
if (success = False) then
begin
WriteLn(ftp.LastErrorText);
Exit;
end;
ftp.Free;
end;
// ---------------------------------------------------------------------------
begin
try
RunDemo;
except
on E: Exception do
WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
end;
WriteLn;
{$IFDEF MSWINDOWS}
WriteLn('Press Enter to exit...');
ReadLn;
{$ENDIF}
end.