Delphi/Pascal 中的代理
Delphi 和 Free Pascal 在开发 Windows 应用方面依然流行。使用代理主要通过 Indy(Delphi 标准库)、Synapse 和 WinINet API 来完成。
Indy(Internet Direct)
Indy 是 Delphi 内置的网络编程库。
HTTP 代理
uses IdHTTP, IdSSLOpenSSL;
procedure FetchViaProxy;
var
HTTP: TIdHTTP;
SSL: TIdSSLIOHandlerSocketOpenSSL;
begin
HTTP := TIdHTTP.Create(nil);
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
HTTP.IOHandler := SSL;
// 代理配置
HTTP.ProxyParams.ProxyServer := 'proxy_ip';
HTTP.ProxyParams.ProxyPort := 8080;
HTTP.ProxyParams.ProxyUsername := 'username';
HTTP.ProxyParams.ProxyPassword := 'password';
HTTP.ProxyParams.BasicAuthentication := True;
WriteLn(HTTP.Get('https://httpbin.org/ip'));
finally
SSL.Free;
HTTP.Free;
end;
end;
通过 Indy 使用 SOCKS5 代理
uses IdHTTP, IdSocks, IdSSLOpenSSL;
procedure FetchViaSocks5;
var
HTTP: TIdHTTP;
SSL: TIdSSLIOHandlerSocketOpenSSL;
Socks: TIdSocksInfo;
begin
HTTP := TIdHTTP.Create(nil);
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
Socks := TIdSocksInfo.Create(nil);
try
// SOCKS5 配置
Socks.Host := 'proxy_ip';
Socks.Port := 1080;
Socks.Version := svSocks5;
Socks.Username := 'username';
Socks.Password := 'password';
Socks.Authentication := saUsernamePassword;
SSL.TransparentProxy := Socks;
HTTP.IOHandler := SSL;
WriteLn(HTTP.Get('https://httpbin.org/ip'));
finally
Socks.Free;
SSL.Free;
HTTP.Free;
end;
end;
SOCKS4
Socks.Version := svSocks4;
// SOCKS4 不支持身份验证
Socks.Authentication := saNoAuthentication;
Synapse
Synapse 是面向 Free Pascal 和 Delphi 的另一个网络库。
安装
从 synapse.ararat.cz 下载并添加到您的项目中。
HTTP 代理
uses httpsend;
procedure FetchViaSynapseProxy;
var
HTTP: THTTPSend;
begin
HTTP := THTTPSend.Create;
try
HTTP.ProxyHost := 'proxy_ip';
HTTP.ProxyPort := '8080';
HTTP.ProxyUser := 'username';
HTTP.ProxyPass := 'password';
if HTTP.HTTPMethod('GET', 'https://httpbin.org/ip') then
WriteLn(HTTP.Document.DataString)
else
WriteLn('Error: ', HTTP.ResultCode);
finally
HTTP.Free;
end;
end;
通过 Synapse 使用 SOCKS
uses blcksock;
procedure FetchViaSynapseSocks;
var
Sock: TTCPBlockSocket;
begin
Sock := TTCPBlockSocket.Create;
try
Sock.SocksIP := 'proxy_ip';
Sock.SocksPort := '1080';
Sock.SocksUsername := 'username';
Sock.SocksPassword := 'password';
Sock.SocksType := ST_Socks5;
Sock.Connect('httpbin.org', '80');
if Sock.LastError = 0 then begin
Sock.SendString('GET /ip HTTP/1.1' + #13#10 +
'Host: httpbin.org' + #13#10 +
#13#10);
WriteLn(Sock.RecvString(10000));
end;
finally
Sock.Free;
end;
end;
WinINet API(Windows)
使用系统 Windows API:
uses WinInet;
procedure FetchViaWinINet;
var
hInternet, hConnect: HINTERNET;
Buffer: array[0..4095] of Char;
BytesRead: DWORD;
begin
// 带代理打开
hInternet := InternetOpen(
'MyApp',
INTERNET_OPEN_TYPE_PROXY,
PChar('http://proxy_ip:8080'),
nil,
0
);
if hInternet <> nil then begin
// 设置代理身份验证
InternetSetOption(hInternet, INTERNET_OPTION_PROXY_USERNAME,
PChar('username'), Length('username'));
InternetSetOption(hInternet, INTERNET_OPTION_PROXY_PASSWORD,
PChar('password'), Length('password'));
hConnect := InternetOpenUrl(hInternet,
'https://httpbin.org/ip', nil, 0,
INTERNET_FLAG_RELOAD, 0);
if hConnect <> nil then begin
InternetReadFile(hConnect, @Buffer, SizeOf(Buffer), BytesRead);
WriteLn(Copy(Buffer, 1, BytesRead));
InternetCloseHandle(hConnect);
end;
InternetCloseHandle(hInternet);
end;
end;
使用系统代理
hInternet := InternetOpen(
'MyApp',
INTERNET_OPEN_TYPE_PRECONFIG, // 使用系统设置
nil,
nil,
0
);
代理轮换
type
TProxyInfo = record
Host: string;
Port: Integer;
Username: string;
Password: string;
end;
var
Proxies: array of TProxyInfo;
ProxyIndex: Integer = 0;
function GetNextProxy: TProxyInfo;
begin
Result := Proxies[ProxyIndex mod Length(Proxies)];
Inc(ProxyIndex);
end;
procedure FetchWithRotation(const URL: string);
var
HTTP: TIdHTTP;
Proxy: TProxyInfo;
begin
Proxy := GetNextProxy;
HTTP := TIdHTTP.Create(nil);
try
HTTP.ProxyParams.ProxyServer := Proxy.Host;
HTTP.ProxyParams.ProxyPort := Proxy.Port;
HTTP.ProxyParams.ProxyUsername := Proxy.Username;
HTTP.ProxyParams.ProxyPassword := Proxy.Password;
try
WriteLn(HTTP.Get(URL));
except
on E: Exception do
WriteLn('Error with proxy ', Proxy.Host, ': ', E.Message);
end;
finally
HTTP.Free;
end;
end;
建议
- Indy 是 Delphi 的标准选择,随 IDE 一起提供
- Synapse 适用于 Free Pascal 和跨平台项目
- WinINet 适用于仅 Windows 的应用,使用系统网络栈
- 使用 SOCKS 时,请用 Indy 的 TIdSocksInfo 或 Synapse 的 SocksType
- OpenSSL DLL —— 使用 HTTPS 时别忘了把 libeay32.dll 和 ssleay32.dll 放在 exe 旁边
结论
Delphi/Pascal 提供了成熟的代理工具。Indy 是最完整的方案,支持 HTTP、SOCKS4、SOCKS5 和身份验证。在 Windows 上处理简单任务时,WinINet API 是一个无外部依赖的快捷选择。
