15
回答
C++实现TCP打洞的思想
开发十年,就只剩下这套Java开发体系了   
1、 S启动两个网络侦听,一个叫【主连接】侦听,一个叫【协助打洞】的侦听。
2、 A和B分别与S的【主连接】保持联系。
3、 当A需要和B建立直接的TCP连接时,首先连接S的【协助打洞】端口,并发送协助连接申请。同时在该端口号上启动侦听。注意由于要在相同的网络终端上绑定到不同的套接字上,所以必须为这些套接字设置 SO_REUSEADDR 属性(即允许重用),否则侦听会失败。
4、 S的【协助打洞】连接收到A的申请后通过【主连接】通知B,并将A经过NAT-A转换后的公网IP地址和端口等信息告诉B。
5、 B收到S的连接通知后首先与S的【协助打洞】端口连接,随便发送一些数据后立即断开,这样做的目的是让S能知道B经过NAT-B转换后的公网IP和端口号。
6、 B尝试与A的经过NAT-A转换后的公网IP地址和端口进行connect,根据不同的路由器会有不同的结果,有些路由器在这个操作就能建立连接,大多数路由器对于不请自到的SYN请求包直接丢弃而导致connect失败,但NAT-A会纪录此次连接的源地址和端口号,为接下来真正的连接做好了准备,这就是所谓的打洞,即B向A打了一个洞,下次A就能直接连接到B刚才使用的端口号了。
7、 客户端B打洞的同时在相同的端口上启动侦听。B在一切准备就绪以后通过与S的【主连接】回复消息“我已经准备好”,S在收到以后将B经过NAT-B转换后的公网IP和端口号告诉给A。
8、 A收到S回复的B的公网IP和端口号等信息以后,开始连接到B公网IP和端口号,由于在步骤6中B曾经尝试连接过A的公网IP地址和端口,NAT-A纪录了此次连接的信息,所以当A主动连接B时,NAT-B会认为是合法的SYN数据,并允许通过,从而直接的TCP连接建立起来了。
各位能说说上面这个过程有什么问题吗?谢谢了
举报
xiaoyaoxing
发帖于7年前 15回/2K+阅
共有15个答案 最后回答: 7年前

TCP打洞好像很有难度

《Windows网络与通讯程序设计》上第10章有讲Tcp打洞,书上讲支持Tcp打洞的NAT只有65%

我有书,但我没看过原理

打洞使应用程序在大多数默认的安全策略下就可以发挥作用,只是TCP NAT穿越的难度要大些,按照这种理论应该可行,只是有很多协议得处理,要不QQ等等软件怎么实现局域网之间的文件传输等功能,不可能都是通过服务端转发吧

引用来自“xiaoyaoxing”的答案

为什么啊!

因为tcp做nat的时候是有状态的。

每个连接要看四个东西(src_ip src_port dst_ip dst_port),这四个都匹配了才认为是同一条连接。中间如果收到了FIN/RST 或者是超时,这条连接就认为是关闭了。

你两边都nat了,怎么连得通?

udp就可以。你的想法就可以实现。

引用来自“xiaoyaoxing”的答案

打洞使应用程序在大多数默认的安全策略下就可以发挥作用,只是TCP NAT穿越的难度要大些,按照这种理论应该可行,只是有很多协议得处理,要不QQ等等软件怎么实现局域网之间的文件传输等功能,不可能都是通过服务端转发吧
use udp

引用来自“ZYud”的答案

引用来自“xiaoyaoxing”的答案

打洞使应用程序在大多数默认的安全策略下就可以发挥作用,只是TCP NAT穿越的难度要大些,按照这种理论应该可行,只是有很多协议得处理,要不QQ等等软件怎么实现局域网之间的文件传输等功能,不可能都是通过服务端转发吧
use udp
TCP 就不行吗
顶部