SOCKET 实现NAT 穿越
在当前IPv4NAT盛行的网络环境下,两个用户要直接进行P2P连接是非常困难的。较好的解决办法是借助含公网的用户或是服务器中介实现P2P连接。
NAT:Network Address Translation,网络地址转换。由于IPv4地址数量十分有限,不可能每一台网络设备都能拥有一个IP。于是NAT技术很好地解决了这个问题。路由设备被ISP分给一个公网地址,路由设备自己生成另外的局域网地址,局域网内部的信息通过路由器的网络地址转换,实现内部网络与外部网络的通信。
对于通常的NAT,当一个内部地址向外部某个网络发送信息:当信息到达NAT设备,NAT设备会首先查询自己的地址转换表。看是否有该内部地址-端口的地址转换表,如果没有,路由器会分配给该地址-端口一个可用的外网端口,并记录在地址转换表中。发送的数据包的源地址会修改为NAT设备的公网地址,端口会变为分配的端口(注意,是直接把IP头部的内容修改了,外部网络是没办法从协议头中知道NAT内部主机的地址的), 然后发送至指定的外部地址。
外部的数据发往内部的某个地址:刚才提到了,外部网络几乎是不知道目的内网的地址的。他只知道该公网路由器的IP和端口(这种情况都是因为内部实现联络了外网才有外部向该内网通信)。外网只关心之前路由器发给他的数据是哪个地址哪个端口。发送信息就朝着这个地址和端口发送。因为NAT设备上有相应的地址转换表。发往改端口的数据会映射到内网的对应地址和端口。
当内网的设备向外网发送数据,NAT设备会使用公网IP以及自己分配的端口为内网设备转发以及接收数据。生成的转换表有会有一定的时限。大多数路由器接收数据要按照内部的地址信任表来,即:内网设备A通过NAT设备S发送至外网设备B,B可以根据S发送过来的端口发给S然后转到A。但是网络中另一个知道A在NAT上的地址与端口的设备C缺不能通过该端口通过S发送到A。因为A没有给C发送数据,路由器S并不信任C只信任B。但如果此时A再向C发送数据,此时就能使得S添加对C的信任,使得C能够通过S发送数据到A。
通过上面的这种理论,我们就能实现不同NAT间的网络穿越。我们需要利用一个中介服务器来传递需要连接的设备在NAT设备上的IP与端口信息。
UDP实现NAT穿越(UDP打洞):
服务器用来接收需要进行NAT穿越的设备在NAT设备上的IP和端口,假如有两个设备A和B要建立连接,他们先要分别向服务器发送一个UDP数据包。服务器可以通过数据包得到A与B在NAT路由器上转换后的IP和端口。此时A向服务器发送一个向B连接的请求,服务器便把B的地址-端口信息发送给A,通知A向B发送连接,并把A的信息发送个给B并通知他连接A。此时A和B都知道对方的IP与端口信息。各自先向对方地址发送一个UDP数据包。这是会有几种情况:
1、A和B都收到了对方发送的数据。(这种情况可能是至少有一个路由器已经信任对方的地址或是路由器不进行地址信任。也可能是网络传输速度慢。两个路由器都发送出数据后,数据才到达两个设备,此时两个设备早已相互信任)
2、A或B只有一个收到了对方发送的数据。(这是最常见的情况,因为两个数据包到达有先后,先发送数据的路由器已经对发送的地址产生了信任,而另一个路由器由于还没有发送数据包就收到了数据,此时它是不信任该地址发过来的数据包的)
3、都没有收到数据包(
a、A或B在NAT设备上的端口发生改变
b、A与B属于同一NAT下,NAT设备不支持回环转换或做了连接限制
c、NAT一个端口只信任一个外部地址
)
如果是第三种情况,可能A与B就不能通过这种环境实现UDP的穿越。对于第二种情况,A与B需要在几秒后再发送几次数据包。如果还是一方全部都收不到。可能收不到这方的NAT设备上的端口发生改变或是NAT一个端口只信任一个外部地址,无法连接。但是通常都能成功的。
说一下移动通信商网络的NAT。中国联通的NAT是这样的:我使用联通设备向服务器发送UDP数据包,服务器获得的端口号是xxx,而我却不能与另一设备实现NAT穿越。最后经我调试发现,我向另一设备发送数据NAT转换后的端口又是另一个端口。我再向服务器发数据,却是原来的xxx端口。查阅资料发现,联通使用的是NAT3,对于不同的地址,NAT转换为不同的端口进行通信。因此不能普通地通过从服务器收到的端口进行连接。
程序实现:
首先两个需要打洞的设备连接上位于公网118.112.50.95 的服务器(受条件限制,其中有一个设备也处于118.112.50.95的公网NAT下)。并获得对方的IP和端口
因为此设备也位于服务器所在的公网下,但是是在NAT后的,他自己的公网ip也是118.112.50.95
对方设备的ip是118.113.89.4
此设备的ip:118.113.89.4,对方的ip为118.112.50.95
然后我们用第一个设备(118.112.50.95)向服务器发起UDP连接(118.113.89.4)的请求,让服务器告知(118.113.89.4)的设备连接自己。之后双方会每隔几秒向对方送一个hellow数据。共发送五次
该设备收到5次hellow
该设备只收到了4次hellow。因为这个设备是被发起连接的设备,所以发送数据包要晚一些。118.112.50.95先发过来的数据包的地址由于不被信任而被丢弃了。当自己向118.112.50.95发出数据包后。服务器开始信任118.112.50.95,于是就收到了118.112.50.95发送过来的剩下的条数据包。
附件所附带的程序是中介服务器与客户端混合在一起的(左边下角,右下角客户端)。左边在公网设置监听端口后就可以用另外的程序连接了。客户端在左上角列表选中要连接的目的地址即通知服务器发起连接。 附件
SOCKET 实现NAT 穿越的更多相关文章
- NAT原理与NAT穿越
最近在看东西的时候发现很多网络程序中都需要NAT穿越,特意在此总结一下. 先做一个约定: 内网A中有:A1(192.168.0.8).A2(192.168.0.9)两用户 网关X1(一个NAT设备)有 ...
- IPFS: NAT traversal(NAT穿越)
IPFS是一个p2p网络,那么一定绕不开的一个问题就是NAT穿越.之前的文章里面也提到过IPFS网络连通性使用的ICE NAT穿越框架,本文简单介绍一下什么是NAT. 为什么有NAT技术? NAT ...
- P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解
1.内容概述 P2P即点对点通信,或称为对等联网,与传统的服务器客户端模式(如下图"P2P结构模型"所示)有着明显的区别,在即时通讯方案中应用广泛(比如IM应用中的实时音视频通信. ...
- VOIP NAT穿越之SIP信令穿越
本文原创自 http://blog.csdn.net/voipmaker 转载注明出处. 本文是VOIP通信NAT系列专题的第三篇, 本文论述NAT对SIP协议穿越的影响.SIP协议是基于文本的,而 ...
- p2p网络中的NAT穿透技术----常见NAT穿越解决方案
转:http://blog.csdn.net/cllzw/article/details/46438257 常见NA丁穿越解决方案 NAT技术在缓解IPv4地址紧缺问题.构建防火墙.保证网络安全等方面 ...
- 转:WebRTC技术及应用2 – NAT穿越技术的使用
评:webrtc自带的打洞,穿透协议. 转: http://www.unclekevin.org/?p=924 959 views WebRTC技术及应用2 – NAT穿越技术的使用 发表回复 (题图 ...
- [ipsec] 特别硬核的ike/ipsec NAT穿越机制分析
〇 前言 这怕是最后一篇关于IKE,IPSEC的文字了,因为不能没完没了. 所以,我一直在想这个标题该叫什么.总的来说可以将其概括为:IKE NAT穿越机制的分析. 但是,同时它也回答了以下问题: ( ...
- (转)NAT与NAT穿越学习总结--ICE过程讲的不错
转:http://cgs1999.iteye.com/blog/1994072 1.引言网络地址转换(Network Address Translation,简称NAT)是一种在IP分组通过路由器或防 ...
- P2P网络穿越 NAT穿越
http://blog.csdn.net/mazidao2008/article/details/4933730 ——————————————————————————————————————————— ...
随机推荐
- hdu5017:补题系列之西安网络赛1011
补题系列之西安网络赛1011 题目大意:给定一个椭球: 求它到原点的最短距离. 思路: 对于一个椭球的标准方程 x^2/a^2 + y^2/b^2 +z^2/c^2=1 来说,它到原点的最短距离即为m ...
- apache2 httpd 基于域名的虚拟主机配置 for centos6X 和debian-8
全系统虚拟主机: for debian 系统的apache2 域名 虚拟主机
- 从有限状态机的角度去理解Knuth-Morris-Pratt Algorithm(又叫KMP算法)
转载请加上:http://www.cnblogs.com/courtier/p/4273193.html 在开始讲这个文章前的唠叨话: 1:首先,在阅读此篇文章之前,你至少要了解过,什么是有限状态机, ...
- Web Service-- 使用 JDK 发布 WS
Web Service,即“Web 服务”,简写为 WS,从字面上理解,它其实就是“基于 Web 的服务”.而服务却是双方的,有服务需求方,就有服务提供方.服务提供方对外发布服务,服务需求方调用服务提 ...
- 泛型 Field 和 SetField 方法 (LINQ to DataSet)
LINQ to DataSet 为 DataRow 类提供用于访问列值的扩展方法:Field 方法和 SetField 方法.这些方法使开发人员能够更轻松地访问列值,特别是 null 值.DataSe ...
- linux的chattr和lsattr命令
chattr是用来改变文件.目录属性.chattr命令的作用很大,其中一些功能是由linux内核版本来支持的.通过chattr命令修改属性能够提高系统的安全性,但是它并不适合所有的目录.lsattr是 ...
- HashSet的分析(转)
一. HashSet概述: HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用null元素. 二. ...
- 关于sed的应用
公司让我做一个看一下在优化的程序和比原来的程序快多少,但是文件还在运行的服务器上,我需要把用到的文件复制到测试服务器上去.但是测试服务器上有的,目录不全,会导致scp出错.就发生了以下的故事. 首选我 ...
- datatable列操作
DataTable myDt =dt; //删除列 myDt.Columns.Remove("minArea"); myDt.Columns.Remove("max ...
- 从blob字段读取图片 在浏览器显示
public byte[] GetProImg(string JID) { byte[] Buffer = null; using (OracleConnection conn = new Oracl ...