路由器|为什么我在公司里访问不了家里的电脑?( 三 )


举个现实中的场景就是 , 你在你家里的电脑上启动了一个HTTP服务 , 地址是192.168.30.5:5000 , 此时你在公司办公室里想通过手机去访问一下 , 却发现访问不了 。
那问题就来了 , 有没有办法让外网机器访问到内网的服务?
有 。
大家应该听过一句话叫 , \"没有什么是加中间层不能解决的 , 如果有 , 那就再加一层\" 。
放在这里 , 依然适用 。
说到底 , 因为NAT的存在 , 我们只能从内网主动发起连接 , 否则NAT设备不会记录相应的映射关系 , 没有映射关系也就不能转发数据 。
所以我们就在公网上加一台服务器x , 并暴露一个访问域名 , 再让内网的服务主动连接服务器x , 这样NAT路由器上就有对应的映射关系 。 接着 , 所有人都去访问服务器x , 服务器x将数据转发给内网机器 , 再原路返回响应 , 这样数据就都通了 。 这就是所谓的内网穿透 。
像上面提到的服务器x , 你也不需要自己去搭 , 已经有很多现成的方案 , 花钱就完事了 , 比如花某壳 。

到这里 , 我们就可以回答文章标题的问题 。
为什么我在公司里访问不了家里的电脑?
那是因为家里的电脑在局域网内 , 局域网和广域网之间有个NAT路由器 。 由于NAT路由器的存在 , 外网服务无法主动连通局域网内的电脑 。
两个内网的聊天软件如何建立通讯
好了 , 问题就叒来了 。
我家机子是在我们小区的局域网里 , 班花家的机子也是在她们小区的局域网里 。 都在局域网里 , 且NAT只能从内网连到外网 , 那我电脑上登录的qq是怎么和班花电脑里的QQ连上的呢?

上面这个问法其实是存在个误解 , 误以为两个qq客户端应用是直接建立连接的 。
然而实际上并不是 , 两个qq客户端之间还隔了一个服务器 。

也就是说 , 两个在内网的客户端登录qq时都会主动向公网的聊天服务器建立连接 , 这时两方的NAT路由器中都会记录有相应的映射关系 。 当在其中一个qq上发送消息时 , 数据会先到服务器 , 再通过服务器转发到另外一个客户端上 。 反过来也一样 , 通过这个方式让两台内网的机子进行数据传输 。
两个内网的应用如何直接建立连接
上面的情况 , 是两个客户端通过第三方服务器进行通讯 , 但有些场景就是要抛开第三端 , 直接进行两端通信 , 比如P2P下载 , 这种该怎么办呢?
这种情况下 , 其实也还是离不开第三方服务器的帮助 。
假设还是A和B两个局域网内的机子 , A内网对应的NAT设备叫NAT_A , B内网里的NAT设备叫NAT_B , 和一个第三方服务器server 。
流程如下:
step1和2: A主动去连server , 此时A对应的NAT_A就会留下A的内网地址和外网地址的映射关系 , server也拿到了A对应的外网IP地址和端口 。
step3和4: B的操作和A一样 , 主动连第三方server , NAT_B内留下B的内网地址和外网地址的映射关系 , 然后server也拿到了B对应的外网IP地址和端口 。
step5和step6以及step7: 重点来了 。 此时server发消息给A , 让A主动发UDP消息到B的外网IP地址和端口 。 此时NAT_B收到这个A的UDP数据包时 , 这时候根据NAT_B的设置不同 , 导致这时候有可能NAT_B能直接转发数据到B , 那此时A和B就通了 。 但也有可能不通 , 直接丢包 , 不过丢包没关系 , 这个操作的目的是给NAT_A上留下有关B的映射关系 。
step8和step9以及step10: 跟step5一样熟悉的配方 , 此时server再发消息给B , 让B主动发UDP消息到A的外网IP地址和端口 。 NAT_B上也留下了关于A到映射关系 , 这时候由于之前NAT_A上有过关于B的映射关系 , 此时NAT_A就能正常接受B的数据包 , 并将其转发给A 。 到这里A和B就能正常进行数据通信了 。 这就是所谓的NAT打洞 。