NAT,网络地址翻译。可能大家并不知道是啥玩意,但是它就在你的身边默默的做着贡献。
只是大家没留意到而已。
比如公司局域网里,要上互联网,需要NAT,
网吧里需要NAT,
家庭网络为了多台机器能上网,需要NAT
校园网也需要NAT,
公共场所免费WIFI,也有NAT,
一个拥有很多用户的ISP服务商,也需要NAT技术.
NAT基本上是无处不在。
有些是作为独立软件实现NAT功能,有些是作为硬件路由器的一部分集成在硬件里。
比如当你在一个支持WIFI的公共场所,打开平板电脑,手机或者笔记本电脑,通过DHCP获得一个随机IP,
然后你就能愉快的畅游互联网,
实际上这个随机获得的IP地址是不能被internet上其他机器访问到的,它是一个内网地址,
WIFI的路由器靠NAT让你能轻松上网。
NAT,网络地址翻译,看名字,就是把一种ip地址变换成另外一种ip地址,让通讯能正常进行。
最初的设计NAT的目的是为了解决IPv4地址枯竭的问题,
它的目的是让内网地址能访问internet互联网。
比如大家很熟悉的 192.168.XX.XX 网段,就属于内网,另外还有
10.XX.XX.XX网段和 172.16.XX.XX网段也属于内网
NAT的种类也比较多,
比较常用的接近大众的是一种叫 NAPT的变种NAT,他做的就是端口映射,
就是把内网地址影射成同一个外网的不同端口。
现在主要讲的就是这个NAPT。
先看看内网的环境搭建:
有一台网关机器,他拥有至少两块网卡, 一块是外网的,
通过ADSL拨号或者其他方式,能上网,并且具有全球唯一的IP地址,
另外一块网卡连接内网的所有机器,拥有192.168.1.1 的IP地址。
内网其他机器都会设置他们的网关为 192.168.1.1 ,这样所有发往internet的数据包都会朝这个网关机器发送。
网关机器上有个NAT程序,他通过内网网卡接收数据包,解释和修改这些数据包,再通过外网网卡发送到internet上去,
同时通过外网网卡接收internet的数据包,解释和修改数据包,并把这些数据包通过内网网卡转发到正确的内网机器上。
NAT程序依靠什么来定位每个数据包究竟该朝那台机器转发呢, 一个通用的处理方式就是端口映射,即NAPT方式。
当内网某台机器第一个发到internet的数据包到达网关程序NAT之后,
NAT程序选择一个空闲的端口号(这是第一个数据包,如果是后续数据包,NAT会根据源IP和源Port来查找映射表),
然后把这个端口号跟这个数据包的源IP和源端口关联起来,
维护到内存里(为了更安全,还应该把目的IP和Port一起关联起来)的映射表里(其实就是一种MAP数据结构)。
这种关联一直存在,一直到超时或者数据包指示断开为止(比如TCP发送FIN数据包)
接着修改这个数据包的源IP为外网网卡的IP,修改源端口为这个选择的空闲端口, 并重新计算校验值,
数据包修改好之后,NAT程序通过外网网卡发送出去。
当internet上的机器回复这个数据到这个外网网卡之后, NAT程序读取到这个数据包,找到数据包的目的端口,
并从映射表中查找外网端口和内部机器的IP-PORT的映射关系。
如果找到,则修改这个数据包的目的IP地址为内部机器IP,修改目的端口号为内部机器的端口号,
最后NAT程序通过内网网卡把这个数据包正确的发送到这个内部机器上去。
这样就完成了数据的交互。
说明白原理之后,其实会恍然大悟的,原来NAPT原理并不复杂的。
当然说的只是NAT中一种情况,NAT还存在多种变种的情况。
顺便一说的是 P2P应用中打洞协议,说起来很神秘,其实作为程序开发的话,显得就比较的简单了。
P2P穿透NAT,大都是针对NAPT方式的,其他方式的NAT穿透基本上成功率都不高,
幸好大部分路由器携带的NAT都是NAPT方式的实现。
从上边的原理中,可以看到,必须是内网机器首先要联系internet中的机器,
才能在NAT网关中留下映射关系,并且这个映射关系一直不变,一直到超时为止。
因此要实现P2P的NAT穿透,也必须首先要内网机器发送数据包到某个公网服务器,
比如A,B是在两个不同NAT之后的内网机器, S是公网中的一台机器。
要实现AB之间直接互相通讯,首先A,B各自发送数据包到公网S,
S记录下A,B机器通过NAT转换之后的外网IP和外网端口,回复对方的外网IP和端口给A,B。
A,B从S得到对方的外网IP和外网端口之后,就不停的朝对方发包,
直到都能接收到对方的数据包为止,这时,A,B双方的洞已经打开,就能互相直接通讯。
一个熟练的程序员实现这样的穿透,可能只要两三百行的代码即可实现。