目录
学了网络之后,我们知道了公网和私网。私网是不能在公网传输和通信的。我们一个学校,一个小区,都是在自己单独的私网里面。通过这个私网内部的路由器(NAPT方式)和外界通信。
那么问题来了,假如我要和其他学校的小伙伴通信,那怎么办呢?我和小伙伴都是在单独的私网里面,而私网的地址是不能通信的,那么我怎么才能和他通信呢?
内网穿透
这就要说到内网穿透了!
如下图,有这么一个环境。小明和小王分别是清华和北大的学生。他们都各自处在自己学校的内网中,他们的ip地址可以是一样的,都是192.168.10.2。清华大学的小明想约北京大学的小王晚上吃饭。于是小明想给小王发一个消息,约她晚上一起吃饭。那么,小明该如何给小王发消息才能让小王收到消息呢?小明只知道小王的ip地址和自己的一样,都是192.168.10.2。很显然,如果小明给192.168.10.2这个ip地址发消息,小王是肯定不能收到消息的。
那么我们就会想,平时我们使用QQ、微信和其他地方、其他学校的小伙伴进行通信,消息是怎么发送的呢?
原因在于QQ和微信在公网有服务器。我们和小伙伴通信是先将消息发送给公网的服务器,公网服务器再将消息发送给位于私网内部的其他小伙伴。数据在我们和小伙伴之间并不是直接传送的。
那么问题又来了?
我们发消息给公网服务器这个可以理解,我们知道他们的公网ip,数据可以到达。但是,公网服务器是如何将我们发送给他的消息发送给位于其他私网内部的小伙伴的呢? 公网服务器并不知道位于私网内部的小伙伴的ip地址。
就算他知道了小伙伴私网边界的路由器的公网ip地址,发消息给路由器的公网ip,路由器收到消息也不会发送给小伙伴,因为在路由器里面并没有一条记录说收到qq或者微信服务器发来的消息然后转发给小王。
就算路由器知道从qq或者微信服务器发来的这条消息是转发给小王的,小王收到这条信息之后也不会接受。因为出于安全起见,除非是主机主动向对方发起了连接请求(这时会在该主机的数据结构中留下一条记录)。否则,当主机接收到数据包时,如果在其数据结构中查询不到对应的记录,那些不请自来的数据包将会被丢弃。
那么我们究竟是如何通过QQ或者微信和其他学校的小伙伴通信的呢?
我们首先看一个简单的情形,位于私网中的我们要访问百度,我们知道百度的域名:www.baidu.com 。于是,我们在浏览器中输入www.baidu.com ,然后我们就可以在百度上查阅我们想查的东西了。域名解析的过程我们不去分析,这个不是本文的重点。这里假设已经将域名进行解析了,解析成了对应的公网ip。当我们访问这个公网ip的时候,我们把流量交给路由器,路由器再根据ip地址请求百度的服务器。百度服务器回消息给路由器,路由器再把消息发送给我们。但是,内网中有这么多机器都是共用路由器的这一个地址,假如同时有好多人访问百度,那么路由器是如何知道百度回的消息是送给小王而不是小李的呢?因为在路由器体内有一个私网ip和端口的对照表,每个私网ip对应一个端口,所以根据端口就能知道消息是发送给内网中的哪台主机了。而我们是主动访问百度的,所以在我们的主机中会有一条记录,当我们接收到百度回的消息时,会接收这条数据。
假如小明以22222端口(随机,大于1024即可)访问百度服务器的80端口,则在我们本地可以看到这么一条连接:
192.168.10.10:22222 <——> 119.75.217.26:80
但是在路由器或者百度服务器上看到的连接则是这样的
100.100.10.10:10000 <——> 119.75.217.26
在路由器体内有这么一条Session记录
192.168.10.10:22222 <——> 10000
当我们访问百度这个事情做完之后的一定时间内,Session记录就会在路由器的体内消失,这个10000端口可以继续分配给其他用户
那么现在我们再来分析一下位于内网中的我们如何和同样是内网中的小伙伴通过QQ通信。
首先,当我们登陆上QQ后,我们就会和QQ的服务器建立一个长连接,基于这个长连接,我们可以给QQ服务器发送消息,QQ服务器也可以给我们发送消息(原理和上面百度的类似)。
我们有小伙伴的QQ号,于是我们给小伙伴QQ号发消息。这个消息通过我们私网边界的路由器发送给了QQ的服务器。QQ的服务器根据QQ号,会查找小伙伴是否在线。如果小伙伴此时也登录上了QQ号的话,那么QQ服务器就会把消息发送给小伙伴。如果小伙伴此时没有登录QQ,那么QQ服务器将不会给小伙伴发送这条消息,因为QQ服务器此时并没有和小伙伴建立长连接,所以他根本不知道小伙伴的位置。只有等小伙伴登录了QQ之后,QQ服务器才会将我们的消息发送给小伙伴。然后小伙伴回消息,后面的过程和之前一样
所以,要让位于两个私网内部主机通信的话,必须得有一个公网的服务器来做中间人,帮我们传递消息。我们私网内部是不能直接通信的!
内网穿透工具
常用的内网穿透的工具有:NAT APP基于ngrok的国内高速内网转发工具
这款软件可以把你内网的ip和端口映射成一个公网的ip和端口,这样,我们就可以实现内网穿透了!
去NAT APP的官网注册一个账号,然后点击购买隧道,选择免费隧道
这里我已经购买过了,所以点击我的隧道,这里可以修改你直接买的配置
然后我们在去运行这个软件, 怎么运行我就不说了,传送门——>Natapp使用教程
./natapp -authtoken=7436320f81b1328e
最后给大家看运行软件的截图,它把我本地192.168.10.27:8888 的端口映射成了公网的 112.74.89.58:41553 ,所以,我们就实现了内网穿透。任何发往 112.74.89.58:41553 端口的数据都会被我们的 192.168.10.27:8888的端口给收到!