今天简单介绍下p2p打洞的原理:
1.什么是NAT?
NAT,全称Network Address Transtrate,是路由器中的一个硬件模块.这个硬件模块主要是用来干什么的呢?
比如我们公司公网肯定只有一个公网ip,然后一台路由,这台路由下我们大概有几十台设备连接上了.
那么这个局域网内的设备路由都会被路由分配一个本地ip,比如:192.168.1.100这样的.
局域网内的每台设备去和外网通信时,NAT都会把局域网内的ip转化为公网的ip,然后随机分配一个port给这个设备,以后只要是这给朝这个port来的数据,路由就知道是给哪个设备的呢.
关于这个port,我们也可以自己指定,但是指定的port如果公网没有用,那么公网就可以直接使用这个port,如果已经使用了,那么就会随机分配一个port.
比如java中我们就是这么指定的:
Socket s = new Socket("47.254.74.253",5596,null,4567);
OutputStream os = s.getOutputStream();
os.write("this is a test".getBytes());
os.close();
如果公网的端口4567没有被使用,那么大家可以在服务器写个程序,打印本地的ip和port,port肯定是4567.
2.打洞的原理.
我们以上图为例,比如设备A/B分别往服务器s发送了数据,这样服务器就知道了A/B设备的公网的ip和port.
但是这里有一个需要注意:
假设这个时候让设备B往设备A发送数据,设备B的数据是可以到达的设备A所在的路由的,但是路由确不会把传输传达给设备A.(这个操作其实就是就是打洞)
为什么呢?
因为这个时候对于设备A来说,设备B的数据属于不请自来的数据,对于不请自来的数据,路由是直接丢弃的.
但是这个时候,让设备A用公网的ip/port朝设备B发送,确可以直接达到设备B.
这又是为什么呢?
因为这个时候B朝A发送了数据,B的NET就已经记录了设备A的地址,知道了B往A发过数据,这个时候A的数据再过来, NAT就会直接把A的数据传达到B.