⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p2p之udp穿透nat的原理与实现 - 增强篇.txt

📁 一个UDP穿透NAT的实例程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
P2P之UDP穿透NAT的原理与实现 - 增强篇(附修改过的源代码)

关键词: P2P UDP NAT 原理 穿透 Traveral Symmetric Cone
原始作者: Hwycheng Leo(FlashBT@Hotmail.com)
源码下载: http://bbs.hwysoft.com/download/UDP-NAT-LEO.rar
参考:http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt
      P2P之UDP穿透NAT的原理与实现(shootingstars)

文章说明:

关于UDP穿透NAT的中文资料在网络上是很少的,仅有<<P2P之UDP穿透NAT的原理与实现(shootingstars)>>这篇文章有实际的参考价值。
本人近两年来也一直从事P2P方面的开发工作,比较有代表性的是个人开发的BitTorrent下载软件 - FlashBT(变态快车). 对P2P下载
或者P2P的开发感兴趣的朋友可以访问软件的官方主页: http://www.hwysoft.com/chs/ 下载看看,说不定有收获。写这篇文章的主要
目的是懒的再每次单独回答一些网友的提问, 一次性写下来, 即节省了自己的时间,也方便了对于P2P的UDP穿透感兴趣的网友阅读和
理解。对此有兴趣和经验的朋友可以给我发邮件或者访问我的个人Blog留言: http://hwycheng.blogchina.com. 
您可以自由转载此篇文章,但是请保留此说明。

再次感谢shootingstars网友的早期贡献. 表示谢意。

----------------------------------------------------------------------------------------------------------------------------

NAT(The IP Network Address Translator) 的概念和意义是什么?

NAT, 中文翻译为网络地址转换。具体的详细信息可以访问RFC 1631 - http://www.faqs.org/rfcs/rfc1631.html, 这是对于NAT的定义和解释的最权威的描述。网络术语都是很抽象和艰涩的,除非是专业人士,否则很难从字面中来准确理解NAT的含义。

要想完全明白NAT 的作用,我们必须理解IP地址的两大分类,一类是私有IP地址,在这里我们称作内网IP地址。一类是非私有的IP地址,在这里我们称作公网IP地址。关于IP地址的概念和作用的介绍参见我的另一篇文章: http://hwycheng.blogchina.com/2402121.html

内网IP地址: 是指使用A/B/C类中的私有地址, 分配的IP地址在全球不惧有唯一性,也因此无法被其它外网主机直接访问。
公网IP地址: 是指具有全球唯一的IP地址,能够直接被其它主机访问的。

NAT 最初的目的是为使用内网IP地址的计算机提供通过少数几台具有公网的IP地址的计算机访问外部网络的功能。NAT 负责将某些内网IP地址的计算机向外部网络发出的IP数据包的源IP地址转换为NAT自己的公网的IP地址,目的IP地址不变, 并将IP数据包转发给路由器,最终到达外部的计算机。同时负责将外部的计算机返回的IP数据包的目的IP地址转换为内网的IP地址,源IP地址不变,并最终送达到内网中的计算机。
                                                 
	----------------------                           ----------------------               
	| 192.168.0.5        |  Internat host            | 192.168.0.6        |  Internat host
	----------------------                           ----------------------               
	        ^ port:2809                                      ^port: 1827                            
	        |                                                |                            
	        V                                                V                            
	----------------------                           ----------------------               
	| 192.168.0.1        | NAT device                | 192.168.0.2        | NAT device    
	| 61.51.99.86        |                           | 61.51.77.66        |               
	----------------------                           ----------------------               
	        ^                                                ^                            
	        |                                                |                            
	        V port:80                                        V port: 80                           
	----------------------                           ----------------------               
	| 61.51.202.88       | Internet host             | 61.51.76.102       | Internet host 
	----------------------                           ----------------------               
                                                            
                              图一: NAT 实现了私有IP的计算机分享几个公网IP地址访问Internet的功能。
                              
随着网络的普及,IPv4的局限性暴露出来。公网IP地址成为一种稀缺的资源,此时NAT 的功能局限也暴露出来,同一个公网的IP地址,某个时间只能由一台私有IP地址的计算机使用。于是NAPT(The IP Network Address/Port Translator)应运而生,NAPT实现了多台私有IP地址的计算机可以同时通过一个公网IP地址来访问Internet的功能。这在很大程度上暂时缓解了IPv4地址资源的紧张。

NAPT 负责将某些内网IP地址的计算机向外部网络发出的TCP/UDP数据包的源IP地址转换为NAPT自己的公网的IP地址,源端口转为NAPT自己的一个端口。目的IP地址和端口不变, 并将IP数据包发给路由器,最终到达外部的计算机。同时负责将外部的计算机返回的IP数据包的目的IP地址转换内网的IP地址,目的端口转为内网计算机的端口,源IP地址和源端口不变,并最终送达到内网中的计算机。

                                                 
		----------------------                           ----------------------               
		| 192.168.0.5        |  Internat host            | 192.168.0.6        |  Internat host
		----------------------                           ----------------------               
			port: 2809	^                   ^ port: 1827
					 \                 /
					  v               v				
					----------------------            
					| 192.168.0.1        | NAT device 
					| 61.51.99.86        |            
					---------------------- 					
	map port:9882 to 192.168.0.5:2809 ^              ^ map port: 9881 to 192.168.0.6:1827
					 /                \
			     port:80	v                  v	port:80				
		----------------------                           ----------------------               
		| 61.51.202.88       | Internet host             | 61.51.76.102       | Internet host 
		----------------------                           ----------------------   				
				
                              图二: NAPT 实现了私有IP的计算机分享一个公网IP地址访问Internet的功能。						
 
在我们的工作和生活中, NAPT的作用随处可见,绝大部分公司的网络架构,都是通过1至N台支持NAPT的路由器来实现公司的所有计算机连接外部的Internet网络的。包括本人在写这篇文章的时候,也是在家中使用一台IBM笔记本通过一台宽带连接的台式机来访问Internet的。我们本篇文章主要讨论的NAPT的问题。

NAPT(The IP Network Address/Port Translator) 为何阻碍了P2P软件的应用?

通过NAPT 上网的特点决定了只能由NAPT内的计算机主动向NAPT外部的主机发起连接,外部的主机想直接和NAPT内的计算机直接建立连接是不被允许的。IM(即时通讯)而言,这意味着由于NAPT内的计算机和NAPT外的计算机只能通过服务器中转数据来进行通讯。对于P2P方式的下载程序而言,意味着NAPT内的计算机不能接收到NAPT外部的连接,导致连接数用过少,下载速度很难上去。因此P2P软件必须要解决的一个问题就是要能够在一定的程度上解决NAPT内的计算机不能被外部连接的问题。

NAT(The IP Network Address Translator) 进行UDP穿透的原理是什么?

TCP/IP传输时主要用到TCP和UDP协议。TCP协议是可靠的,面向连接的传输协议。UDP是不可靠的,无连接的协议。根据TCP和UDP协议的实现原理,对于NAPT来进行穿透,主要是指的UDP协议。TCP协议也有可能,但是可行性非常小,要求更高,我们此处不作讨论,如果感兴趣可以到Google上搜索,有些文章对这个问题做了探讨性的描述。下面我们来看看利用UDP协议来穿透NAPT的原理是什么:

			----------------------                           ----------------------               
			| 192.168.0.5        |  Internat host            | 192.168.0.6        |  Internat host
			----------------------                           ----------------------               
			  UDP port: 2809	^                   ^ UDP port: 1827
						 \                 /
						  v               v				
						----------------------            
						| 192.168.0.1        | NAT device 
						| 61.51.99.86        |            
						---------------------- 					
  Session(192.168.0.6:1827 <-> 61.51.76.102:8098) ^              ^ Session(192.168.0.6:1827 <-> 61.51.76.102:8098)
               map port:9882 to 192.168.0.5:2809 /                \map port: 9881 to 192.168.0.6:1827
				  UDP port:8098	v                  v	UDP port:8098				
			----------------------                           ----------------------               
			| 61.51.202.88       | Internet host             | 61.51.76.102       | Internet host 
			----------------------                           ---------------------- 		
							
					
		                      图三: NAPT 是如何将私有IP地址的UDP数据包与公网主机进行透明传输的。

UDP协议包经NAPT透明传输的说明:

NAPT为每一个Session分配一个NAPT自己的端口号,依据此端口号来判断将收到的公网IP主机返回的TCP/IP数据包转发给那台内网IP地址的计算机。在这里Session是虚拟的,UDP通讯并不需要建立连接,但是对于NAPT而言,的确要有一个Session的概念存在。NAPT对于UDP协议包的透明传输面临的一个重要的问题就是如何处理这个虚拟的Session。我们都知道TCP连接的Session以SYN包开始,以FIN包结束,NAPT可以很容易的获取到TCP Session的生命周期,并进行处理。但是对于UDP而言,就麻烦了,NAPT并不知道转发出去的UDP协议包是否到达了目的主机,也没有办法知道。而且鉴于UDP协议的特点,可靠很差,因此NAPT必须强制维持Session的存在,以便等待将外部送回来的数据并转发给曾经发起请求的内网IP地址的计算机。NAPT具体如何处理UDP Session的超时呢?不同的厂商提供的设备对于NAPT的实现不近相同,也许几分钟,也许几个小时,些NAPT的实现还会根据设备的忙碌状态进行智能计算超时时间的长短。

		  [192.168.0.6:1827]
                            | UDP Packet[src ip:192.168.0.6 src port:1827 dst ip:61.51.76.102 dst port 8098]
                            v
	[pub ip: 61.51.99.86]NAT[priv ip: 192.168.0.1]
                            | UDP Packet[src ip:61.51.99.86 src port:9881 dst ip:61.51.76.102 dst port 8098]
                            v			
		  [61.51.76.102:8098]
		  
		  		    图四: NAPT 将内部发出的UDP协议包的源地址和源端口改变传输给公网IP主机。
		  		    
		  		    
		  [192.168.0.6:1827]
		            ^
                            | UDP Packet[src ip:61.51.76.102 src port:8098 dst ip:192.168.0.6 dst port 1827]
	[pub ip: 61.51.99.86]NAT[priv ip: 192.168.0.1]
		            ^	
                            | UDP Packet[src ip:61.51.76.102 src port:8098 dst ip:61.51.99.86 dst port 9881]	
		  [61.51.76.102:8098]
		  
		  		    图五: NAPT 将收到的公网IP主机返回的UDP协议包的目的地址和目的端口改变传输给内网IP计算机。		  		    
现在我们大概明白了NAPT如何实现内网计算机和外网主机间的透明通讯。现在来看一下我们最关心的问题,就是NAPT是依据什么策略来判断是否要为一个请求发出的UDP数据包建立Session的呢?主要有一下几个策略: 

A. 源地址(内网IP地址)不同,忽略其它因素, 在NAPT上肯定对应不同的Session
B. 源地址(内网IP地址)相同,源端口不同,忽略其它的因素,则在NAPT上也肯定对应不同的Session

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -