使用 C# 在复杂网络上添加 NAT UPnP 映射
我正在创建一个应用程序,该应用程序通过 tcp 连接侦听来自不同应用程序(客户端)的连接(服务器)。因此,如果两个应用程序位于同一网络上,则很容易建立连接。因此,我尝试向服务器添加一种方法,以便用户不必打开路由器上的端口即可使应用程序在通过互联网使用时正常工作。那么让我向您展示几个不同的场景:
1)---------------------------------------- -------------场景_1------------------------------------ -------------------------
服务器是房子里的一台电脑。该计算机连接到路由器,并且该路由器连接到互联网。客户端是办公室中的一台也可以访问互联网的计算机。
为了使这种情况发挥作用,之前我经常打开家庭路由器上的端口并将它们转发到服务器计算机。在客户端上,我只需提供正确的 IP 地址和相同的端口即可建立连接。
现在我用一种非常酷的技术避免打开家庭路由器上的端口:
首先我添加此参考:
然后我告诉路由器我想要将哪些端口转发到我的计算机(服务器):
NATUPNPLib.UPnPNATClass upnpnat;
NATUPNPLib.IStaticPortMappingCollection mappings;
public ServerExample()
{
InitializeComponent();
// server local IP address
mappings.Add(1300, "TCP", 1300, "192.168.0.120", true, "my server");
//.... etc
..
执行此操作时,我可以通过提供端口 1300(另一台服务器计算机的 WAN IP 地址)从我的办公室计算机进行连接。 (该地址可以在以下位置找到:whatismyipaddress.com)最酷的事情是我不必在路由器上进行任何配置!
2)------------------------------------------------------------场景_2 ----------------------------------------------------------
知道我的来了问题。服务器恰好在办公室。该服务器连接到路由器A,路由器A连接到路由器B,路由器B连接到互联网。在其他方面,此示例类似于服务器上的最后一个示例,中间有一个额外的路由器。而客户在其他地方。我们不关心客户端计算机上的网络设置如何,只要它可以访问互联网即可。
我用来解决这个问题的方法是将包从路由器 x 转发到服务器计算机,并将流量从路由器 B 的端口 x 端口转发到路由器 A 的 IP 地址。在设置该配置时,我能够建立一个提供服务器的 WAN IP 地址时与客户端建立连接。 (从办公室网络检索时显示的 IP 地址:whatismyipaddress.com)。
因此,如果我可以避免在路由器上进行所有这些配置并执行类似的操作,那就太好了:
public delegate void SomeDelegate(string parameters);
NATUPNPLib.UPnPNATClass upnpnat;
NATUPNPLib.IStaticPortMappingCollection mappings;
public ServerExample()
{
InitializeComponent();
// server local IP address
mappings.Add(1300, "TCP", 1300, "192.168.150.141", true, "my server");
mappings.Add(1300, "TCP", 1300, "another ip", true, "router's ip");
所以我一直在玩这个,但我无法使其工作。如果我能找出服务器连接是否类似于 c# 的场景 1 或场景 2 或者可能是不同的场景,这样设置服务器的用户不必指定所有这些信息,那就太好了。例如,我确信 Limewire 会做类似的事情。
编辑:
这里是场景 1 所示:
这里是场景 2 所示
I am creating an application that listens for connections (server) from a different application (client) via a tcp connection. So if both application where to be on the same network it will be easy to establish the connection. so I am trying to add a method to the server so that users do not have to open ports on their routers in order to make the app work when using it over the internet. so let me show you a few different scenarios:
1)---------------------------------------------------SCENARIO_1-------------------------------------------------------------
the server is a computer in a house. That computer is connected to a router and that router is connected to the internet. The client is a computer on a office that has access to the internet as well.
for this scenario to work, before I used to open the ports on the house router and forward them to the server computer. on the client I just had to supply the correct IP address and same port in order to establish the connection.
now I avoided opening the ports on the house router with a really cool technique:
first I add this reference:
then I tell the router which ports I want to be forwarded to my computer (the server):
NATUPNPLib.UPnPNATClass upnpnat;
NATUPNPLib.IStaticPortMappingCollection mappings;
public ServerExample()
{
InitializeComponent();
// server local IP address
mappings.Add(1300, "TCP", 1300, "192.168.0.120", true, "my server");
//.... etc
..
when doing this I am able to connect from my office computer by providing port 1300, the WAN ip address of the server computer which is a different one. (that address can be found at: whatismyipaddress.com) THE COOL THING IS THAT I DO NOT HAVE TO DO ANY CONFIGURATION ON THE ROUTER!!!
2)-----------------------------------------------SCENARIO_2----------------------------------------------
know here comes my problem. The server happens to be on a office. that server is connected to router A, router A is connected to router B and router B is connected to the internet. In other this example is like the last example on the server with an extra router in between. and the client is somewhere else. we do not care how the network setup is on the client computer as long as it has internet access.
the way I used to solve this was by forwarding the packages from router x to the server computer and also port forwarding the traffic from port x of router B to the ip address of router A. when setting up that configuration I was able to establish a connection with the client when providing the WAN ip address of the server. (the ip address that is shown at: whatismyipaddress.com when retrieved from the network of the office).
so it will be nice if I can avoid doing all this configuration on the routers and do something similar to:
public delegate void SomeDelegate(string parameters);
NATUPNPLib.UPnPNATClass upnpnat;
NATUPNPLib.IStaticPortMappingCollection mappings;
public ServerExample()
{
InitializeComponent();
// server local IP address
mappings.Add(1300, "TCP", 1300, "192.168.150.141", true, "my server");
mappings.Add(1300, "TCP", 1300, "another ip", true, "router's ip");
so I have been playing around with that and I have not been able to make it work. also it will be nice if I could find out if the server connection is like scenario 1 with c# or scenario 2 or maybe a different scenario so that the users setting up the server do not have to specify all that info. for example I am sure that limewire does something similar.
Edit:
here is scenario 1 illustrated:
and here is scenario 2 illustrated
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您正在使用的功能称为通用即插即用(UPnP),这基本上是一种方式让一个设备告诉另一个设备如何与其通信。您所做的就是告诉计算机告诉路由器您想要转发到它的端口。不幸的是,UPnP 是一种不可路由的协议,这意味着它无法跨越路由器。因此,简短的答案是,如果不手动配置距离客户端“最远”的路由器,您正在尝试的操作将无法与多个路由器一起工作。
可能可以使用互联网网关设备协议 (IDG) 但您必须进行更多研究,而您所针对的库不支持这一点。将此问题发布到服务器故障,您可能会得到更好的答案。 (不要发布你的代码,只需解释你的问题的基础知识,你试图让一台机器使用 UPnP 向路由器注册自身,该路由器正在工作,但你前面有另一个路由器,你想自动转发, 也。)
The feature that you are using is called Universal Plug and Play (UPnP) which is basically a way for a device to tell another device how to communicate with it. What you are doing is telling a computer to tell the router what ports you want forwarded to it. Unfortunately UPnP is a non-routable protocol which means that it can't jump across routers. So the short answer is that doing what you are trying will not work with multiple routers without manually configuring the ones "farthest" away from the client.
It might be possible to do something with Internet Gateway Device protocol (IDG) but you'd have to research that more and the library you are targeting doesn't support that. Post this question to Server Fault and you might get a better answer. (Don't post your code, just explain the basics of your problem, that you're trying to have a machine register itself with a router using UPnP which is working but you have another router in front of that that you want to automatically forward, too.)