我正在使用C / POSIX进行P2P应用程序而且我遇到了NAT遍历问题。
我读到了多种方法(MiniUPnP,手动端口转发,TCP / UDP打孔)以及很多关于它的问题,但我发现了一些问题:
- MiniUPnP :我看到传输cli使用它来进行端口转发,所以我下载了MiniUPnP的源代码并尝试理解它,但它太多了一团糟,放弃了。我搜索了类似文档来实现它(比如“ this function <\ n> < / em>“)但没有找到任何有用的东西。 (我认为这是最干净的方法,因为它只需要使用为此目的而创建的库。如果有人知道如何使用该代码,请帮助我)
- 手动端口转发:我希望用户不要弄乱路由器的设置,所有的工作都应该通过代码完成。
- TCP打孔:我读过关于打孔的this article,我认为这是最简单的方法(我也有一个带有公共IP的VPS,所以我可以使用它像集合点服务器一样)但我无法管理连接不同NAT后面的两个不同用户。
方案
我有一个主服务器(在VPS上),记录加入p2p网络的每个对等体,这就是:
- PeerA加入网络并向服务器发送这对夫妇(A_LOCAL_IP:A_LOCAL_PORT);
- 服务器保存A的公共IP(X.X.X.X)及其公共端口(AAA)以及从A发送的一对。
- PeerB加入网络并向服务器发送这对夫妇(B_LOCAL_IP:B_LOCAL_PORT)
- 服务器保存B的公共IP(Y.Y.Y.Y)和他的公共端口(BBB)以及从B发送的那对夫妇。
- PeerA和PeerB都进入for循环,等待accept(),然后它们产生一个线程来处理传入的请求
- PeerA希望与PeerB连接
- PeerA询问服务器,PeerB的IP:端口
- 服务器向PeerA发送两对(Y.Y.Y.Y:BBB)和(B_LOCAL_IP:B_LOCAL_PORT)[最后一个以防它们属于同一个NAT]
- PeerA产生一个线程,该线程进入for循环尝试连接或通过端口“BBB”与“YYYY”进入或通过端口“B_LOCAL_PORT”进入“B_LOCAL_IP”,而“主线程”进入for循环尝试接受连接
- 服务器向PeerB发送两对(X.X.X.X:AAA和(A_LOCAL_IP:A_LOCAL_PORT)
- PeerB产生一个线程,该线程进入for循环尝试连接或通过端口“AAA”与“XXXX”连接或通过端口“A_LOCAL_PORT”进入“A_LOCAL_IP”,而“主线程”进入for循环尝试接受连接
醇>
这是交易:当我使用(B_LOCAL_IP:B_LOCAL_PORT)对时,它工作正常;当我使用(Y.Y.Y.Y:BBB)情侣时,它不起作用。
我在“ECONNREFUSED”的情况下使用指数后退,当我尝试使用(Y.Y.Y.Y:BBB)情侣打印时
连接被拒绝。睡1秒
拒绝连接。睡2秒左右
拒绝连接。睡4秒
拒绝连接。睡8秒
拒绝连接。睡16秒
拒绝连接。睡32秒
最大超时已到期。中止...
当然,当另一个NAT下的某个人试图加入我的NAT下的同伴时,也会发生这种情况。
所以就是这样,而且这是我的问题:
- 为什么使用(B_LOCAL_IP:B_LOCAL_PORT)对,而不使用(Y.Y.Y.Y:BBB)对呢?
- 我的NAT是否有可能使某些配置/架构无法实现通孔?
醇>