解决网络通讯中外网和内网之间的通讯问题(NAT转换)

本文原址 http://www.cnblogs.com/lidabo/p/3828846.htmlhtml

在网络编码中会发现程序在局域网中是能够适用的,可是在外网与内网之间和内网与内网之间就不可行。
问题就在于NAT。首先介绍下NAT。 
NAT的做用NAT(Network Address Translator),网络地址转换。顾名思义,它是一种把内部私有网络IP地址翻译成公有网络IP地址的技术,如图5-1所示。NAT是在IP地址日益缺少的状况下产生的,它的主要目的是使地址可以重用[9]。 
解决外网与内网或内网之间的通讯,NAT穿透 - sanerye - DreamEyesSKY 
图5-1 NAT模型 
IP地址分为五类:A类,B类,C类,D类,E类(这里不考虑保留的IP地址)。A、B、C类可被计算机做为IP地址,D类为组播地址,E类为特殊用途的地址。A、B、C类中,又可分为公有地址和私有地址,私有地址用于内网,不一样的内网,私有地址可重用,从而节省了公网地址,它不可在公网中被路由,因此内网的主机要访问公网的服务器,便要通过NAT。公有地址是全球惟一的,能在公网上被路由。 
解决外网与内网或内网之间的通讯,NAT穿透 - sanerye - DreamEyesSKY 
内网主机用私有地址在内网能与其它的内网主机无误地通讯,但它不能直接用私有地址访问外网的主机,由于私有地址不能被路由。它要与外网通讯,必须通过NAT设备(如网关,路由器),如图5-2所示。主机A与服务器S通讯,它须先经过网关,此时网关改变它的数据包地址及端口,把私有地址(10.0.0.2)改成公有地址(155.99.25.11),使数据包能在公网上被路由,送至服务器端。服务器端返回的数据包到达网关后,网关把公网地址改成相应的私有地址,而后转发到主机A。经过这种方法,一个内网只需一个公有IP地址,就把整个内网的计算机接入Internet,从而解决IP地址缺少的问题。 
NAT功能一般被集成到路由器、防火墙、ISDN路由器或者单独的NAT设备中。也可经过软件实现这一功能,Windows 98 SE、Windows 2000 都包含了这一功能。 
NAT的分类及工做原理 
解决外网与内网或内网之间的通讯,NAT穿透 - sanerye - DreamEyesSKY 

基本NAT与NAPT如图5-3所示,NAT分为两大类,基本的NAT和NAPT(Network Address/Port Translator)[10][11]。 
基本的NAT,它仅将内网主机的私有IP地址转换成公网IP地址,但并不将TCP/UDP端口信息进行转换,有动态与静态之区分。因为如今大部分都属于另外一种类型,即NAPT,故这里不详细讨论基础NAT。 
另一种NAT叫作NAPT(Network Address/Port Translator),从名称上咱们也能够看得出,NAPT不但会改变通过这个NAT设备的IP数据报的IP地址,还会改变IP数据报的TCP/UDP端口。NAPT的地址及端口的转换过程,请看图5-4: 
解决外网与内网或内网之间的通讯,NAT穿透 - sanerye - DreamEyesSKY 
私有网络中某一主机Client A(10.0.0.2),它的某个进程经过1234端口,想访问外网服务器18.181.0.31的1235端口。那么当数据包经过NAT时,这个NAT的外网地址是155.99.25.11,首先NAT会改变这个数据包的原IP地址,改成155.99.25.11。并分配一个端口(如62000)给Client A,把数据包的原端口号改成62000。因此原本是(10.0.0.2:1234->18.181.0.31:1235)的数据包到了互联网上变为了(155.99.25.11:62000->18.181.0.31:1235),如图5-4左图所示。NAT会记住62000端口对应的是10.0.0.2的1234端口,之后从外网服务器18.181.0.31发送到62000端口的数据会被NAT自动的改变目的IP和端口号,而后转发到10.0.0.2上(如图5-4右图所示) 
锥型NAT与对称型NAT 
解决外网与内网或内网之间的通讯,NAT穿透 - sanerye - DreamEyesSKY 

NAPT又分为锥型(Cone)和对称型(Symmetric),如图5-5所示,它们的区别在于,在NAT已分配端口号给Client A的状况下,若是Client A继续用1235端口与另外一外网服务器通信,锥型NAT还会继续用原来62000端口,即所分配的端口号不变。而对于对等型NAT,NAT将会分配另外一端口号(如62001)给Client A的1235端口。也就是说,同一内网主机同一端口号,对于锥型NAT,不管与哪一外网主机通信,都不改变所分配的端口号;而对于对等型NAT,同一内网主机同一端口号,每一次与不一样的外网主机通信,就从新分配另外一个端口号。 
彻底锥型NAT、受限制锥型NAT与端口受限制型NAT 
锥型NAT可另外分类为彻底锥形(Full Cone)NAT,受限制锥形(Restricted Cone)NAT,端口受限制锥形(Port Restricted Cone)NAT。 
①彻底锥形(Full Cone)NAT 
这种NAT内部的主机A链接过外网主机C后,NAT会打开一个端口。而后外网的任何发到这个打开的端口的UDP数据报均可以到达A,不论是不是C发过来的[12]。 
例如 A: 192.168.8.100  NAT: 202.100.100.100  C: 292.88.88.88 
A(192.168.8.100:5000) -> NAT(202.100.100.100:8000) -> C(292.88.88.88:2000) 
任何发送到NAT(202.100.100.100:8000)的数据均可以到达A(192.168.8.100:5000)。 
②受限制锥形(Restricted Cone)NAT 
这种NAT内部的主机A链接过外网的主机C后,NAT打开一个端口。而后C能够用任何端口和A通讯,但其余的外网主机不能够。 
例如 A: 192.168.8.100  NAT: 202.100.100.100  C: 292.88.88.88 
A(192.168.8.100:5000) -> NAT(202.100.100.100:8000) -> C(292.88.88.88:2000) 
任何从C发送到NAT(202.100.100.100:8000)的数据均可以到达A(192.168.8.100:5000)。 
③端口受限制锥形(Port Restricted Cone)NAT 
这种NAT内部的主机A链接过外网的主机C后,NAT打开一个端口。而后C只能用原来的端口和A通讯,其余的外网主机不能够。 
例如 A: 192.168.8.100  NAT: 202.100.100.100  C: 292.88.88.88 
A(192.168.8.100:5000) -> NAT(202.100.100.100:8000) -> C(292.88.88.88:2000) 
只有C(202.88.88.88:2000)发送到 NAT(202.100.100.100:8000)的数据均可以到达A(192.168.8.100:5000)。 
NAT产生的问题 
NAT很好地解决了地址紧缺的问题,屏蔽了内部网络,但也带来一些问题。内网的主机向外链接是很容易的(NAT至关于透明的,内网的和外网的主机均不用知道NAT的状况)。但若是外部的计算机想访问子网内的计算机就比较困难了,这可使内网主机先发起链接从而解决问题。可是若是两台主机都分别位于两不一样NAT后面时,两台主机没法通讯。当分别位于两不一样NAT(NAT A,NAT B)后面的两台主机A和B欲进行通信时,若主机B主动发起链接,它该连哪一个地址呢?第一种状况:试图直接连到主机A的内网私有地址(10.0.0.2:1234)确定会失败,由于10.0.0.2根本就不是一个能够在公网上路由的IP地址;第二种状况,试图直接连到B的NAT公有地址(155.99.25.11:62000),NAT A会拒绝这个数据包,由于这个端口并没有绑定内网主机的某个端口,或即便有所绑定,但这个端口所绑定的外网地址和端口并非B的地址和端口。若A主动链接B,结果同样。 
有两种方法解决这个问题。方法一:经过服务器,服务器做为中间人,转发主机间的数据。但若用户数量到达必定数目时,这方法浪费带宽且给服务器带来很大压力,因此方法不可行。方法二,仍是经过服务器,但服务器只充当“介绍人”,不转发主机间的数据,具体请看下面的“UDP打孔技术” (UDP hole punching) 
穿透NAT——UDP打孔技术 
所谓的“打孔技术”,就是在内网的NAT设备上打上一个“孔”(也就是在NAT上创建一个会话,绑定地址和端口号),这个孔不能由外部来打,只能由内网内的主机来打。并且这个孔多是有方向的,好比从内部某台主机(好比:192.168.0.10)向外部的某个IP(好比:219.237.60.1)发送一个UDP包,那么就在这个内网的NAT设备上打了一个方向为219.237.60.1的“孔”,之后219.237.60.1就能够经过这个孔与内网的192.168.0.10联系了[13]。 
下面就根据NAT的各类类型详细解析如何“打孔”,如何穿透NAT。 
1.彻底锥形(Full Cone)NAT 
处于不一样内网的主机A和主机B,各自先链接服务器,从而在各自NAT设备上打开了一个“孔”,服务器收到主机A和主机B的链接后,知道A与B的公网地址和NAT分配给它们的端口号,而后把这些NAT地址与端口号告诉A与B,因为在彻底锥形NAT的特色,A和B给服务器所打开的“孔”,能给别的任何的主机使用。故A与B可链接对方的公网地址和端口直接进行通讯。服务器在这里充当“介绍人”,告诉A与B对方的地址和端口号。 
2.受限制锥形(Restricted Cone)NAT 
A和B仍是要先链接服务器,服务器发送A和B的地址和端口信息给A和B,但因为受限制锥形NAT的特色,他们所打开的“孔”,只能与服务器通讯。要使他们能够直接通讯,解决办法以下: 
假如主机A开始发送一个UDP信息到主机B的公网地址上,与此同时,它又经过服务器中转发送了一个邀请信息给主机B,请求主机B也给主机A发送一个UDP信息到主机A的公网地址上。这时主机A向主机B的公网IP发送的信息致使NAT A打开一个处于主机A的和主机B之间的会话,与此同时,NAT B也打开了一个处于主机B和主机A的会话。一旦这个新的UDP会话各自向对方打开了,主机A和主机B之间就能够直接通讯了[14]。 
3.端口受限制锥形(Port Restricted Cone)NAT 
对于该类型的NAT,解决办法跟上面的方法同样。 
4.对称型(Symmetric)NAT 
对称型NAT,对于不一样的外网主机地址,它都会分配不一样的端口号,因此进行UDP打孔比较困难,但也能够进行端口预测打孔,不过不能保证成功。 
以上的穿透NAT,是对NAPT来进行穿透,主要是针对UDP协议。TCP协议也有可能,可是可行性很是小,要求更高。而且,语音视频通讯是用UDP传输的,故针对TCP的NAT穿透在这里不做讨论。基础NAT不修改通过的数据包的端口号,它们能够看做是彻底锥形NAT的精简版本,即基础NAT也能够被穿透。NAT设备将在必定时间后关闭UDP的一个映射,因此为了保持与服务器可以一直通讯,服务器或客户端必需要周期性地发送UDP包,保持映射不被关闭。 
目前比较经常使用的NAT类型是彻底锥型NAT 
 解决外网与内网或内网之间的通讯,NAT穿透 - sanerye - DreamEyesSKY 
如图6-7所示,步骤以下: 
①客户端A发UDP数据报经NAT A,把数据发送到服务器。NAT A分配端口给客户端A。服务器接收到信息后,把客户端A经NAT A后的地址及端口信息记录下来。 
②客户端B发UDP数据报经NAT B,把数据发送到服务器。NAT B分配端口给客户端B。服务器接收到信息后,把客户端B经NAT B后的地址及端口信息记录下来。 
③ 服务器把客户端B的地址及端口信息发送给客户端A,把客户端A的地址及端口信息发送给客户端B,客户端A、B就能够经过所得到的对方的地址及端口号进行通讯了。服务器

相关文章
相关标签/搜索