我需要建立从家用计算机到办公室计算机的tcp连接。

在办公室,有一台路由器,其中连接了多台计算机。该路由器具有互联网,因此连接到该路由器的所有计算机也都具有互联网。在我家里,我有一台可以上网的计算机。我需要我的办公室计算机充当服务器,并且需要我的家用计算机连接到该服务器。以前,我以前能够通过端口转发服务器上的流量来进行连接,如下所示:

    NATUPNPLib.UPnPNATClass upnpnat;
    NATUPNPLib.IStaticPortMappingCollection mappings;

    public ServerExample()
    {
        InitializeComponent();

        upnpnat = new NATUPNPLib.UPnPNATClass();
        mappings = upnpnat.StaticPortMappingCollection;

        //                           server local IP address
        mappings.Add(1300, "TCP", 1300, "192.168.150.146", true, "plsease work");
        // this code tels the router to forward all tcp traffic comming from port
        // 1300 to the server computer (it's lan ip address happens to be 192.168.150.146)
        //...

这样我就可以从家中建立连接(我知道简单的方法是打开办公室路由器上的端口并将其转发到我的计算机,问题是我无法访问办公室路由器)

现在他们用较新的路由器替换了我办公室中的路由器,但我现在无法使用我的代码。现在,使用新的路由器,当我执行私有(private)代码时,我得到:

注意映射返回null;因此,我无法添加映射。

我确信应该有一种建立连接的方法,因为办公室中的某些人会使用例如limewire或比特洪流。我认为我的问题可能与权限有关?我该如何解决?

编辑

因此,通过研究,我发现我要尝试的是“UDP打洞进入防火墙”。我实际上想通过TCP连接进行操作。我不知道tcp和upd puch钻孔之间会有什么区别....我的意思是说,这样做的目的是使客户端无需在路由器上进行配置即可找到一个梨。













更新

好的,所以我相信我已经尝试使用C#来解决你们在这个问题上发布的问题:好的,让我向您展示我做了什么:

请注意,您可能需要引用此图才能理解我将要解释的内容:

如您所知,我想在计算机A和计算机B之间建立tcp连接。我设法做到这一点的方法是做所谓的tcp穿孔。

步骤1:
我要做的第一件事是开始监听服务器S上的新连接。
                   TcpListener server = new TcpListener(System.Net.IPAddress.Parse(“192.168.11.109”), 55550);
                   Server.Start();

                   var client = server.AcceptSocket();  \\ wait here until someone connects

第2步:
现在以以下方式使用计算机A连接到服务器:
          TcpClient tcpClient = new TcpClient("192.168.11.109", 55550);

第三步:
在计算机A上执行第2步代码后,服务器S调试应如下所示:

第四步:
现在我们的目标是从计算机B连接到计算机A。服务器S具有B建立连接所需要的信息。实际上,我将必须在计算机B和服务器S之间建立连接,以便服务器S可以为B提供适当的参数,以使B连接到A。

步骤5:
由于正在调试,因此我能够看到参数,因此我现在将通过监听端口3313使计算机A成为服务器。我希望计算机A现在正在该端口(3313)监听,因为所有带有端口的软件包都已发送到路由器X 3313应该发送到计算机A。
       \\ COMPUTER A
       TcpListener server = new TcpListener(System.Net.IPAddress.Parse("192.168.0.120"), 3313);
        server.Start();

        var newClient = server.AcceptSocket();  \\ wait here until a client gets connected

步骤6:
因此,计算机A现在应该在端口3313上监听新连接。端口3313同样重要,因为路由器x应该将从该端口接收的所有数据包转发到计算机A。

计算机A正在等待新的连接。

步骤7:
所以现在快点!我们想要建立与计算机B的连接。实际上,服务器S会传递参数,但是由于我只是想进行这项工作,因此我将在计算机B上很快地编写程序。
          TcpClient tcpClient = new TcpClient(“192.168.11.108”, 3313);
           \\192.168.11.108  is the address of router X

最后:

由于某些原因,计算机B无法连接到计算机A。

它之所以无法连接,是因为路由器X没有将软件包转发到计算机A。(我知道这是因为我在路由器X的端口54540上启用了端口转发,并且当我使用该端口时它可以工作)我的意思是不明白为什么路由器X不能将来自端口3313的流量转发到计算机A。计算机A已经建立了到服务器S的连接,并且服务器S通过端口3313发送到路由器X的所有东西都被发送到了计算机A。为什么是如果我通过端口3313将数据包发送到路由器X,它们将不会被计算机A接收!

PS:

请注意,我在此处显示的所有内容实际上都具有三个路由器X,Y和Z,并且还具有服务器S,计算机A和计算机B:

最佳答案

您的新工作路由器可能已禁用UPnP,因此为空引用。

否则,由于路由器不知道将入站数据包发送到何处,因此无法使服务器对入站流量可见。在这种情况下,路由器将充当防火墙,阻止进入服务器的传入流量。

解决此问题的基本方法是:

1)打开UPnP

这使您的应用程序可以指示路由器如何将入站流量转发回服务器。

2)设置端口转发

如上通过手动配置路由器。

3)使您的工作服务器成为客户端

路由器通过允许出站连接启动连接来工作。它记住返回地址,重写外部可见的IP,并为外部流量提供未使用的端口以进行回叫(NAT)。这允许出站请求与外部建立通信并绕过防火墙。如果您的家庭IP是固定的,则可以在工作中设置一个客户端,尝试按计划调用家庭(直到启动服务器并可以建立连接)。

4)使用P2P(中介服务器)

我不确定从哪里开始,但是原理是这样。它通常在单个UDP端口上工作。不在NAT之后的服务器用于建立连接。客户端以UDP数据包的形式将其IP发送到服务器,然后路由器用路由器的返回地址重写UDP header 。服务器获取此数据并将其发送给其他对等方。现在,每个人都知道彼此的返回地址,他们可以直接向彼此发送TCP流量,并且服务器会自动退出。

关于NAT的基础,有一些非常好的文章here,用简单的术语进行了解释。好的文章here解释了P2P如何利用NAT绕过防火墙。

希望这能给您一些想法。

关于c# - 使用C# "UDP punch hole into firewall"将流量从端口X转发到计算机B,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7225150/

10-16 15:58