1、用户A登录服务器S,服务器S记录用户A经NAT转换后的地址。
2、用户B登录服务器S,服务器S记录用户B经NAT转换后的地址。
3、用户A想与用户B建立P2P通信。
4、用户A向服务器发送请求,告诉服务器想与用户B建立P2P通信。
5、服务器S接收到用户A发送过来的请求后,将B经NAT转换后的地址放在一个(可以称之为)回馈的消息包中发送给用户A。
6、同时,服务器S将A想与B通信的消息(消息中包含了A经NAT转换后的地址)告知B。
7、A接收到服务器S发送过来的回馈消息后(包含B经NAT转换后的地址),开始不停向这个地址发送数据Message。
8、B在接收到服务器S发送过来的A想与之建立P2P通信的消息之后,向这个地址发送一次打洞包,表示我接受来自这个地址的数据。
9、如果B接收到了A发送过来的Message数据。B向服务器告知的A的地址发送回馈包Message ACK,如果A接收到了Message ACK,说明数据已经打通。
问题:
除Symmetric NAT之外的三种NAT类型,一旦内部向外发送了数据,其地址及端口的映射就不会改变,就是说所有向外部发送的数据都是使用这个映射。
区别是: 完全锥型NAT在建立映射后,任何外部地址可以通过NAT分配的地址和端口与内网用户通信。限制锥型NAT在建立映射后,只有内网通过NAT分配的地址及端口发送过的地址用户(可以是不同的端口)才能与内网用户通信。那么最后一个端口限制锥型,自己想是什么样的情况。
1、Symmetric NAT的真实运作情况?
就称之为对称型NAT。对称型NAT与上面有一个很大的不同,就是相同的端口对应不同的目的地址(不是说NAT,是说“目的”地址),就会有不同的地址及端口的映射。为什么说这种类型不能通过打洞的方式解决呢?来看一个例子。
EXAMPLE:
A是一个对称型NAT后的用户。
B是一个其它类型NAT后的用户。
1、A,B登录服务器;
2、服务器记录两者的NAT转换后的地址及端口;
3、A呼叫B;
4、服务器给A和B对方的地址;
5、A向B发送数据Message,服务器给A的BNAT转换后的地址是对的。开始时候B没有打洞,如果是B所处的NAT是锥型的(锥型,一旦地址端口对了的可是来者不拒),B收到数据Message。如果B所处的是限制锥型或是端口限制锥型,则发送失败(被B的NAT据之门外了,所以B接收不到);
6、B为A打洞,但是,A的NAT地址对B来说是假的!那是A对应与服务器的时候,NAT给他分配的。
7、A还是在给B发送数据,现在B打洞了(它认为它给A打洞了),但是现在A用的不是B打洞的那个NAT地址及端口给B发送的。B的服务器就将其丢弃,B还是收不到!当然6、7中的分析仅仅说的是限制锥型或是端口限制锥型,因为A掌握的B的NAT地址是正确的。
上面是一种情况。A->B
来看B->A
A为B打了一个洞,可是B不会将数据发到了服务器给它的那个地址端口上,而不是发送到这个为其专门新建的NAT映射地址端口上,B主动发给A是不可能的了。
这里这样可以看出来,如果B所处的是限制锥型或是端口限制锥型NAT,则不管A发给B还是B发给A,数据都不会收到的。
B是完全锥型是不是还存有一线希望呢?
A给B发送消息,B能够收到数据包,B利用这个地址给A发送反馈消息,相当于为其打了一个洞,A就收到了B的反馈。
这样是可以通讯的。
对称型NAT之后的用户A应该能与完全锥型或者无NAT的用户B建立P2P通信的。
关于网上某个程序的一点分析
服务器记录了A以及B经NAT(如果有)转换后的地址端口。
A和B分别从服务器获取到对方的注册地址端口后,
此时A发给B消息,由于服务器上记录的B的NAT转换后的地址是有效的,A能够将数据发送给B,B就能根据这个数据中携带的地址信息与A通信,发送一个反馈。这就是我们能收到ACK的原因。(这里,表示双发已经能够通信了,那么,现在程序中B为什么不能向A发送数据,因为程序中,它使用的是当时服务器给它的那个地址端口,这个肯定不会一样)
B利用服务器给他的A经NAT转换后的地址端口发给A,不管A有没有打洞(因为打洞是对应了另外一个端口),A都是不会收到B过来的数据的。