Delphi:TCP 打孔

Posted

技术标签:

【中文标题】Delphi:TCP 打孔【英文标题】:Delphi: TCP Hole Punching 【发布时间】:2018-02-22 12:38:09 【问题描述】:

我正在尝试在 Delphi 中进行 TCP 打孔。我只打开了一个端口 - 10000(用于测试目的)。

这是我的代码的 sn-p (full source code):

procedure TFormMain.btnEnableRedirectClick(Sender: TObject);
begin
  IdTCPServerRetr.Active:=True;
end;

procedure TFormMain.btnConnectToClientClick(Sender: TObject);
begin
  if IdTCPClientRemote.Port = 0 then
    ShowMessage('Wait for connection to redirect server...')
  else begin
    IdTCPClientRemote.Host:=MyIP;
    IdTCPClientRemote.Connect;
    ShowMessage('S U C C E S S');
  end;
end;

procedure TFormMain.btnConnectClick(Sender: TObject);
begin
  IdTCPClientLocal.Host:=MyIP;
  IdTCPClientLocal.Connect;
  ShowMessage('Connected to redirect server!');
end;

procedure TFormMain.btnListenClick(Sender: TObject);
begin
  IdTCPServerLocal.DefaultPort:=IdTCPClientLocal.Socket.Binding.Port;
  IdTCPServerLocal.Active:=True;
  ShowMessage('Local server started!');
end;

procedure TFormMain.IdTCPServerRetrExecute(AContext: TIdContext);
begin
  IdTCPClientRemote.Port:=AContext.Connection.Socket.Binding.PeerPort;
end;

首先,我在端口 10000 上运行远程服务器(用于重定向)。

IdTCPServerRetr.Active:=True;

之后,我连接到重定向服务器(端口 10000)并创建本地服务器,使用与客户端相同的端口。

IdTCPClientLocal.Connect; IdTCPServerLocal.DefaultPort:=IdTCPClientLocal.Socket.Binding.Port; IdTCPServerLocal.Active:=True;

(客户端和服务器有一个reusesocket = rsTrue

之后,我尝试通过其内部端口连接到客户端,但收到错误“Connection Timeout”。

我认为问题是远程客户端找不到要连接的服务器,因为客户端已经与重定向服务器建立了连接。

【问题讨论】:

我必须阅读 TCP 打孔才能理解,因为我不知道它是什么。如果我理解正确,它依赖于让双方都尝试打开一个连接,并且让套接字 both 发送一个 SYN 数据包 并且 期望一个可选的 SYN-ACK,我我不确定 Indy 是否支持这一点。 【参考方案1】:

尝试将TIdTCPClient.ConnectTimeout 设置为较高的值,例如5000 或更多(毫秒)。

【讨论】:

以上是关于Delphi:TCP 打孔的主要内容,如果未能解决你的问题,请参考以下文章

分享一个Delphi跨平台Http库的封装,一个Delphi跨平台TCP库的封装

Delphi 11 - tcp:64311:无法解析名称:没有与主机名关联的地址退出

DELPHI中TCP如何广播

Delphi最简化异步选择TCP服务器

Delphi最简化异步选择TCP服务器

Wiki:Delphi 第 3 方 TCP/IP 组件库的最新技术