学了网络之后,我们知道了网络有:公网和私网。
私网是不能在公网传输和通信的。
我们一个学校,一个小区,都是在自己单独的私网里面。通过这个私网内部的路由器(NAPT方式)和外界通信。
我和小伙伴都是在单独的私网里面,而私网的地址是不能通信的,那么我怎么才能和他通信呢?
使用:内网穿透
这就要说到内网穿透了!
如下图,有这么一个环境。
小明和小王分别是清华和北大的学生。他们都各自处在自己学校的内网中,他们的ip地址可以是一样的,都是192.168.10.2。
清华大学的小明想约北京大学的小王晚上吃饭。于是小明想给小王发一个消息,约她晚上一起吃饭。那么,小明该如何给小王发消息才能让小王收到消息呢?
小明只知道小王的ip地址和自己的一样,都是192.168.10.2。很显然,如果小明给192.168.10.2这个ip地址发消息,小王是肯定不能收到消息的。
原因在于QQ和微信在公网有服务器。
我们和小伙伴通信是先将消息发送给公网的服务器 > 公网服务器再将消息发送给位于私网内部的其他小伙伴。
数据在我们和小伙伴之间并不是直接传送的,必须有一个公网的服务器中转!
我们发消息给公网服务器这个可以理解,我们知道他们的公网ip,数据可以到达。
但是,
公网服务器并不知道位于私网内部的小伙伴的ip地址。
就算他知道了小伙伴私网路由器的公网ip地址,发消息给路由器的公网ip,路由器收到消息也不会发送给小伙伴,因为在路由器里面并没有一条记录说收到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服务器才会将我们的消息发送给小伙伴。然后小伙伴回消息,后面的过程和之前一样
所以,要让位于两个私网内部主机通信的话,必须得有一个公网的服务器来做中间人,帮我们传递消息。我们私网内部是不能直接通信的!内网穿透工具
常用的内网穿透的工具有:NAT APP基于ngrok的国内高速内网转发工具
这款软件可以把你内网的ip和端口映射成一个公网的ip和端口,这样,我们就可以实现内网穿透了!
去NAT APP的官网注册一个账号,然后点击购买隧道,选择免费隧道按照提示填写内容,然后我们在去运行这个软件, 怎么运行我就不说了,传送门——>Natapp使用教程
最后给大家看运行软件的截图,它把我本地192.168.10.27:8888 的端口映射成了公网的 112.74.89.58:41553 ,所以,我们就实现了内网穿透。任何发往 112.74.89.58:41553 端口的数据都会被我们的 192.168.10.27:8888的端口给收到!