使用适用于 Delphi 的 Indy Internet Direct 和 Linux 上的 Lazarus,我开发了一个充当代理的应用程序,目的是根据客户端的 IP 地址将客户端重定向到不同的内容。
为此,我使用了
TIdMappedPortTCP
对象。
OnConnect
通知事件,并更改AContext.Binding.Port
。OnBeforeConnect
通知事件代替。Binding.Port
但在 OnContextCreate
上。TIdMappedPortTCP.MappedPort
作为示例,我尝试了 2 号,它会覆盖
OnBeforeConnect
。我认为这次尝试失败了,因为现阶段 AContext.Connection.Connected
已经是 true
,但我找不到比这更早修改它的方法。
procedure TMapperApplication.OnBeforeConnect(AContext: TIdContext);
var
IP, Host: string;
var
I: integer;
begin
// List
Inc(ConnectionCount);
AddConnection(AContext);
// Write
WriteDate;
IP := AContext.Binding.PeerIP;
Host := GStack.HostByAddress(IP);
TConsole.TextColor := TConsoleColor.LightMagenta;
TConsole.Write := 'Incoming connection from ';
TConsole.TextColor := TConsoleColor.LightBlue;
TConsole.Write := Format('"%S" (%S) on port %D', [Host, IP, AContext.Binding.Port]);
WriteNewLn;
// Common date
WriteDate;
// Redirect port
for I := 0 to High(Servers) do
if IP = Servers[I].Source then
begin
AContext.Binding.IP:=Servers[I].Host;
AContext.Binding.Port:=Servers[I].Port;
TConsole.TextColor := TConsoleColor.Yellow;
TConsole.Write := 'Mapped connection to ';
TConsole.ResetStyle;
TConsole.WriteLn:=Format('%S:%D', [Servers[I].Host, Servers[I].Port]);
ResetNewLn;
Exit;
end;
// Default mapping
if EnableDefault then
begin
AContext.Binding.IP:=Servers[I].Host;
AContext.Binding.Port:=Servers[I].Port;
Mapper.Active:=true;
TConsole.WriteLn:='Mapped connection to default host.';
Exit;
end;
// Mapping failed
TConsole.TextColor:=TConsoleColor.Red;
TConsole.WriteLn:='Connection was dropped. No mapping found.';
AContext.Connection.Disconnect;
TConsole.ResetStyle;
end;
解决这个问题后,我计划替换IP地址检测,并使用一种方法来检测
server1.site.com
和server2.site.com
,但我不确定这在Delphi中是否可以通过可用的库实现。我尝试了 GStack.HostByAddress(AContext.Binding.PeerIP)
,但返回一个空字符串。下次有问题。
我也会搜索
www.indyproject.org
,但似乎网络服务器目前已关闭。下载不起作用。还有this,但它没有提供任何对这个问题有用的信息。
我还发现了this旧论坛,但不幸的是,该解决方案似乎已经过时,因为
TIdMappedPortThread
是一个未定义的声明,并且未在TIdMappedPortTCP
中使用。还有this,但它也已经过时了。
所以目前我已经用尽了所有的想法。也许创建自定义
TIdMappedPortTCP
会有帮助?但我现在不确定。
您找到的旧解决方案适用于 Indy 9,但它仍然适用于 Indy 10。只需在 Indy 10 中将
TIdMappedPortThread
替换为 TIdMappedPortContext
。
您无法更改
AContext.Binding.Port
,即客户端连接到代理的侦听端口。要更改代理转发到的下一个位置,您必须将 AContext
转换为 TIdMappedPortContext
,然后将其 OutboundClient
转换为 TIdTCPClient
,然后根据需要设置其 Host
和 Port`。