我正在开发一个需要启用TCP Hole Punching的P2P应用程序。
对于 Rendezvous 服务器,我使用一个简单的应用程序(在公共IP中运行),其中TIdTCPServer
启用了SSL,此应用程序维护客户端连接并返回连接客户端的公共端点(AContext.Binding.PeerIP和AContext.Binding.PeerPort)。
与服务器的客户端(TIdTCPClient
)连接将ReuseSocket属性设置为rsTrue
。
这是客户端连接到 Rendezvous 服务器的方式。
TCPClientMain.ConnectTimeout := 500;
TCPClientMain.Host := RendezvousServerIP;
TCPClientMain.Port := RendezvousServerPort;
TCPClientMain.UseNagle := false;
TCPClientMain.ReuseSocket := rsTrue;
OpenSSLHandlerMain.UseNagle := false;
OpenSSLHandlerMain.ReuseSocket := rsTrue;
TCPClientMain.IOHandler := OpenSSLHandlerMain;
TCPClientMain.Connect();
当我尝试从 B 直接创建客户 A 的公共终点时,会出现此问题。
var
LTCPClient : TIdTCPClient;
LOpenSSLHandle : TIdSSLIOHandlerSocketOpenSSL;
begin
//Init the SSL for the new connection
LOpenSSLHandle := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
LOpenSSLHandle.SSLOptions.Method := TIdSSLVersion.sslvTLSv1_2;
LOpenSSLHandle.SSLOptions.SSLVersions := [sslvTLSv1_2];
LOpenSSLHandle.UseNagle := False;
LTCPClient := TIdTCPClient.Create(nil);
LTCPClient.ConnectTimeout := 5000;
//Set the data of the public end point of the Client A
LTCPClient.Host := ARemoteIPAddress; //This is the public ip of the Client A
LTCPClient.Port := ARemotePort; //This is the port of the public endpoint of the client A
LTCPClient.ReuseSocket := rsTrue;
LTCPClient.IOHandler := LOpenSSLHandle;
LTCPClient.Connect(); //This raises a EIdSocketError exception
我收到套接字错误#10061连接被拒绝。
那么,问题是如何在不引发异常的情况下建立与客户端的公共端点的新连接?