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

在网络编码中会发现程序在局域网中是可以适用的,但是在外网与内网之间和内网与内网之间就不可行。
问题就在于NAT。首先介绍下NAT。 
NAT的作用NAT(Network Address Translator),网络地址转换。顾名思义,它是一种把内部私有网络IP地址翻译成公有网络IP地址的技术,如图5-1所示。NAT是在IP地址日益缺乏的情况下产生的,它的主要目的是使地址能够重用[9]。 
 
图5-1 NAT模型 
IP地址分为五类:A类,B类,C类,D类,E类(这里不考虑保留的IP地址)。A、B、C类可被计算机作为IP地址,D类为组播地址,E类为特殊用途的地址。A、B、C类中,又可分为公有地址和私有地址,私有地址用于内网,不同的内网,私有地址可重用,从而节省了公网地址,它不可在公网中被路由,所以内网的主机要访问公网的服务器,便要经过NAT。公有地址是全球唯一的,能在公网上被路由。 
 
内网主机用私有地址在内网能与其它的内网主机无误地通信,但它不能直接用私有地址访问外网的主机,因为私有地址不能被路由。它要与外网通信,必须经过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与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: 
 
私有网络中某一主机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 

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 
  
如图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就可以通过所获得的对方的地址及端口号进行通信了。

解决网络通信中外网和内网之间的通信问题(NAT转换)的更多相关文章

  1. 解决外网与内网或内网之间的通信,NAT穿透

    在网络编码中会发现程序在局域网中是可以适用的,但是在外网与内网之间和内网与内网之间就不可行.问题就在于NAT.首先介绍下NAT. NAT的作用NAT(Network Address Translato ...

  2. 利用端口映射解决:拥有公网IP有限,内网需要访问因特网

    动态端口映射:   内网中的一台电脑要访问新浪网,会向NAT网关发送数据包,包头中包括对方(就是新浪网)IP.端口和本机IP.端口,NAT网关会把本机IP.端口替换成自己的公网IP.一个未使用的端口, ...

  3. 外网访问内网的FTP服务器

    转自 外网访问内网的FTP服务器 首先感谢作者给出的总结,原文是介绍Serv-U的,我针对FileZilla Server进行了稍微修改,仅看操作可直接跳到分割线后第3部分. 1. 背景简介最近研究如 ...

  4. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  5. 如何通过IP地址分辨公网、私网、内网、外网

    如何通过IP地址分辨公网.私网.内网.外网   内.外网是相对于防火墙而言的,在防火墙内部叫做内网,反之就是外网.   在一定程度上外网等同于公网,内网等同于私网.   地址为如下3个区域就是处于私网 ...

  6. 使用ssh从外网访问内网

    一.场景如下: 各个角色的对应关系如下: 角色 描述 APP 个人笔记本,属于内网IP sshd server 公网 VPS ( 映射端口: port 2222 ),拥有公网IP ssh client ...

  7. 【NetWork】外网和内网

    外网和内网 2019-11-16  11:22:37  by冲冲 1.内网 ① 内网的电脑们,需要经过交换机.路由器,才能访问Internet(外网). ② 因为外网IP比较紧张,现在的电脑普及使得外 ...

  8. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  9. windows 双网卡同时上专网(内网)和外网

    本操作是用网线做专网(内网),无线网卡用于外网 1. 记录有线网卡的网络的网关,例如10.103.14.1 2. 有线网卡必须是手动指定的ip地址,把网关清掉,例如 3. 删除0.0.0.0 路由 r ...

随机推荐

  1. 201521123111《Java程序设计》第7周学习总结

    1. 本章学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 线性表,栈,队列,哈希表是常用的数据结构 在java.util包中有这些数据结构的实现类.比如:List接口,实现类Arra ...

  2. 201521123001《Java程序设计》第2周学习总结

    本周学习总结 码云可以很方便地储存我们写好的代码,不用在写代码的时候担心没带U盘 Java中有许多已经写好的具有特定功能的一段独立小程序,不需要每一个函数都自己编写 Java的float型和C语言的不 ...

  3. 201521123068 《java程序设计》 第13周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1.网络基础 1.1 比较ping www.baidu.com与ping cec.jmu. ...

  4. 201521123118《java程序与设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容 2. 书面作业 1. 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synch ...

  5. Java第十二周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  6. [ JDK ] 列表转数组 toArray

    <T> T[] toArray(T[] a) :该方法返回一个数组,数组元素包含了 List<T> 中的所有元素,数组中的元素顺序和 List<T> 中的元素顺序保 ...

  7. Atom的追踪函数插件和自定义语法

    atom网盘链接:http://pan.baidu.com/s/1nvt7vJz 密码:om26 追踪函数插件 直接使用最新autom版本傻瓜式安装 名字:goto-definition 地址:htt ...

  8. centOS7网络配置(nmcli,bonding,网络组)

    关于网络接口命名 CentOS 6之前,网络接口使用连续号码命名: eth0. eth1等,当增加或删除网卡时,名称可能会发生变化.CentOS 7使用基于硬件,设备拓扑和设置类型命名. 网卡命名机制 ...

  9. Hibernate第六篇【多对多映射、一对一映射】

    前言 前面已经讲解了一对多和多对一的映射是怎么配置了,也讲解了inverse和cascade属性对关联关系的影响,本博文讲解多对多的映射和一对一的映射! 多对多映射 需求:一个项目由多个员工开发,一个 ...

  10. echo和print的区别

    1.echo可以同时输出多个字符串: echo 'this',' string',' is'," hello world\n"; 2.print有返回值,但是运行速度上echo比较 ...