基于P2P协议通信模式的选型(二)
我们继续昨天的话题。昨天我们讲到UDP hole punching,应该说,它给我们提供了一个基本的概念,就是想要A与B建立通信通道,就得要相互向对方的外部IP以及端口发送UDP包,这样逻辑连接就建立起来了。然而它的问题在于这种模式是必须依赖于cont NAT的特性的,倘若每次连接NAT都动态分配一个端口,那么UDP hole punching技术就会失效。针对这种情况,下面再介绍一种方法。
4、UDP端口猜测(UDP Port Number Prediction)
这个方法,可以用来对付非cone NAT的,如对称NAT,原本不想介绍的,本人觉得大家都是搞科学的,这种猜测的事情....不过从方法论上将,确是一种思路,姑且一听。同样分别处于NAT-A与NAT-B后面的终端A与B想要相互通信,借助于一个暴露共知点S,AB分别向S发包,S将他们的外部地址和外部端口交换给对方。在对称NAT下,新建连接是一次分配端口号的,那么A向B的外部地址的外部端口+1发送UDP包,同样的B向A的外部地址的外部端口+1发送UDP包,考虑到时间很短,中间不会有新的连接建立,那样就可以在他们下次分配新端口号的时候,正好找准了。如我开头所说,这种方法实在太不保险了,太多的因素都会导致失败,应用也非常的少。
5、TCP同时打开(Simultaneous TCP Open)
这个是跟TCP连接的建立机制有关的,因为TCP连接一般是一个终端向另一个终端发送SYN包,对方同步响应一个SYN-ACK包。而Simultaneous TCP Open即A、B两个终端同时向对方发送同步包,用ACK响应包来建立连接。正常情况下,当有TCP SYN包发送到middlebox的时候,middlebox会丢弃它,或者发送TCP RST包来拒绝外部访问的连接尝试。但是若源地址端口、目的地址端口的TCP SYN同步包同时到达的时候,middlebox会认为这个TCP连接已经被建立了,就会允许数据包通过。和上面的四种方法类似,同样通过S知道AB已经建立的Tcp连接端口号,预计下一个Tcp连接会分配下一个端口,向对方发送SYN数据包,在对方SYN数据包到达自己所处middlebox之前,自己发出的SYN数据包通过了该middlebox,middlebox就会认为Tcp连接已经建立,如此就可以建立起Tcp连接。这种方法和第4种方法有着类似的思路,但是却比第四种方法还要敏感脆弱,因为你甚至根本没有办法保证A出的SYN包一定比B发出的SYN包先到达NAT-A。
通过上述,我们发现,目前还没有一种完美的或者标准的方法来进行跨NAT的通信,但是比较明显的是,在NAT存在的下面进行P2P通信,UDP是首选。
UDP hole punching技术是在同处NAT之后的终端进行通信最有效率的技术,并且可以在多种现有NAT上使用,因此,对于一般需求的P2P通信,通常建议使用这种方法。但是当直接通信没有办法建立的时候,也就是说P2P没有办法实现,那么我们不得不借助S进行转发。
另外需要说明的是,相当多的终端并不止一个IP地址,因此,你也许并不知道该向服务器上报哪一个。通常的建议是将所有的IP地址都上报上去,因为或许,这两个终端正使用双网卡处于同一个NAT下面。

浙公网安备 33010602011771号