如何连接到具有与另一台外部IP相同的外部IP的特定计算机?

时间:2018-12-31 17:09:46

标签: sockets delphi tcp

想象一下有关远程访问应用程序的以下情况。

我有两个Server-Client应用程序和一个Server-only应用程序(使用动态DNS)。

当我启动(1)Server-Client应用程序时,它立即连接到服务器,并在ListView中显示它的ID /密码/ IP /端口,因此当我启动(2)Server-客户端应用程序,然后按连接,它将遍历服务器ListView上的每个ID /密码/ IP /端口元素,并带给我有关ID /密码的IP /端口。

问题在于所有这些应用程序都使用相同的外部IP /端口,因此我的应用程序不知道要连接哪台计算机。

我已经在此处发布了此问题,但由于缺少详细信息,因此已将其删除。我将再次发布它,并且还将提供一些代码。

起初,我虽然需要为每个服务器客户端提供DNS服务,但这太乱了,可能对我没有帮助(我将尝试使用IndyDNSServer和IndyDNSResolver组件)。

在我第一次在这里发布问题后,用户告诉我尝试使用TCustomWinSocket

Data属性->

http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/ScktComp_TCustomWinSocket_Data.html

但是我什么也做不了。

//This block here passes the IP/Port configuration to the other 
application socket (ClientS stands for ClientSocket[Number]).

ClientS2.Host := ClientS1.Host;
ClientS2.Port := ClientS1.Port;
ClientS3.Host := ClientS1.Host;
ClientS3.Port := ClientS1.Port;
ClientS4.Host := ClientS1.Host;
ClientS4.Port := ClientS1.Port;
ClientS5.Host := ClientS1.Host;
ClientS5.Port := ClientS1.Port;
ClientS6.Host := ClientS1.Host;
ClientS6.Port := ClientS1.Port;

MyFirstBmp := TMemoryStream.Create;
MySecondBmp := TMemoryStream.Create;
MyCompareBmp := TMemoryStream.Create;
PackStream := TMemoryStream.Create;
iSendCount := 0;
StatusBar1.Panels.Items[1].Text := 'Connected';
Timer2.Enabled := true;
BitBtn1.Enabled := false;
edtIPAddr.Enabled := false;
edtPort.Enabled := false;
edtPassword.Enabled := false;
edtName.Enabled := false;
frmCConectaNovaTela.bbtConecta.Enabled;

Sleep(1000);
Socket.SendText('<|MAIN|>');  // This text makes it so that the Main 
thread on the server application be created.

我试图找到一种方法,使我的应用程序连接到一台特定计算机,该计算机具有与同一网络中其他也在使用我的应用程序并且在其ServerSockets上具有相同侦听端口的其他计算机相同的外部IP

用一个理想的词来说,我会喜欢...

CS1.Host := '188.156.124.111';
CS1.Port := '32500';
CS1.Property := 'ThirdParameterToMakeADistinctConnection';

2 个答案:

答案 0 :(得分:3)

正如我确定的告诉您的那样,您不能仅使用IP来识别特定方。只是不够独特。

您可以使用TCustomWinSocket.Data属性来跟踪所需的任何用户定义数据。例如,当客户端登录到服务器时,您可以存储其用于入站连接的公共IP /端口,其唯一ID(用户名等),等等。

当一个客户端想要向另一个客户端发送消息时,它可以要求服务器将消息中继到所需的ID。服务器可以在其客户端列表中查找ID,然后在找到消息后中继消息。

当设备位于路由器后面时,为了从外部网络到特定设备进行入站连接,路由器必须启用端口转发,并在其中打开公共端口将所有接收到的流量转发到设备的专用LAN IP /端口。

对于点对点连接,客户端1应该向客户端2发送一条消息,要求其打开侦听端口,然后客户端2应该以客户端1可以连接的公共IP /端口进行回复。

如果客户端2在路由器后面,则它需要像往常一样在本地打开侦听端口,然后用路由器上打开的适当的公共转发IP /端口进行回复。它可以使用uPNP要求路由器动态打开转发端口(如果路由器不支持uPNP,则必须由路由器管理员事先静态配置转发端口。)

如果连接失败,则让客户端反转角色,然后客户端2要求客户端1打开侦听端口,以供客户端2连接。

答案 1 :(得分:1)

如果我正确理解了您的问题,则需要NAT。

这是一个非常简化且不完整的解释。为了简单起见,我尝试仅通过TCP端口对其进行解释。

您的专用网络中有两台计算机,A(192.168.0.100)和B(192.168.0.200)。在您的示例188.156.124.111中,两者在路由器等后面都有相同的公共地址。

现在,您必须在路由器上创建NAT规则。像这样:

  • 外部端口32500到A(192.168.0.100)上的内部端口32500
  • 外部端口32501到B(192.168.0.200)上的内部端口32500

您的客户端现在可以通过端口32500建立与A的连接,并通过端口32501建立与B的连接。您的服务器应用程序仍然在32500上进行监听。