在当前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 穿越的更多相关文章

  1. NAT原理与NAT穿越

    最近在看东西的时候发现很多网络程序中都需要NAT穿越,特意在此总结一下. 先做一个约定: 内网A中有:A1(192.168.0.8).A2(192.168.0.9)两用户 网关X1(一个NAT设备)有 ...

  2. IPFS: NAT traversal(NAT穿越)

    IPFS是一个p2p网络,那么一定绕不开的一个问题就是NAT穿越.之前的文章里面也提到过IPFS网络连通性使用的ICE NAT穿越框架,本文简单介绍一下什么是NAT.   为什么有NAT技术? NAT ...

  3. P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解

    1.内容概述 P2P即点对点通信,或称为对等联网,与传统的服务器客户端模式(如下图"P2P结构模型"所示)有着明显的区别,在即时通讯方案中应用广泛(比如IM应用中的实时音视频通信. ...

  4. VOIP NAT穿越之SIP信令穿越

    本文原创自 http://blog.csdn.net/voipmaker  转载注明出处. 本文是VOIP通信NAT系列专题的第三篇, 本文论述NAT对SIP协议穿越的影响.SIP协议是基于文本的,而 ...

  5. p2p网络中的NAT穿透技术----常见NAT穿越解决方案

    转:http://blog.csdn.net/cllzw/article/details/46438257 常见NA丁穿越解决方案 NAT技术在缓解IPv4地址紧缺问题.构建防火墙.保证网络安全等方面 ...

  6. 转:WebRTC技术及应用2 – NAT穿越技术的使用

    评:webrtc自带的打洞,穿透协议. 转: http://www.unclekevin.org/?p=924 959 views WebRTC技术及应用2 – NAT穿越技术的使用 发表回复 (题图 ...

  7. [ipsec] 特别硬核的ike/ipsec NAT穿越机制分析

    〇 前言 这怕是最后一篇关于IKE,IPSEC的文字了,因为不能没完没了. 所以,我一直在想这个标题该叫什么.总的来说可以将其概括为:IKE NAT穿越机制的分析. 但是,同时它也回答了以下问题: ( ...

  8. (转)NAT与NAT穿越学习总结--ICE过程讲的不错

    转:http://cgs1999.iteye.com/blog/1994072 1.引言网络地址转换(Network Address Translation,简称NAT)是一种在IP分组通过路由器或防 ...

  9. P2P网络穿越 NAT穿越

    http://blog.csdn.net/mazidao2008/article/details/4933730 ——————————————————————————————————————————— ...

随机推荐

  1. stardict词典(星际译王)

    sudo apt-get install stardict 下载词库: http://abloz.com/huzheng/stardict-dic/zh_CN/ 把下载的压缩包解压,以a为例cd /u ...

  2. Android静态变量使用陷阱

    静态变量大家再熟悉不过了,本来没什么好重复的.事情起因是这样的,最近测试那边反应正在做的一个产品总是莫名其妙的显示不出某些数据,甚至闪退崩溃,仔细查了几遍发现没什么问题,最后百般周折发现在那部测试机上 ...

  3. Android 编程下的计时器

    在安卓 APP 的手机号注册逻辑中,经常会有将激活码发送到手机的环节,这个环节中绝大多数的应用考虑到网络延迟或服务器压力以及短信服务商的延迟等原因,会给用户提供一个重新获取激活码的按钮.如下图所示: ...

  4. jQuery制作焦点图(轮播图)

    焦点图(轮播图) 案例 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...

  5. windows服务器性能监控工具、方法及关键指标

    原文:http://www.cnblogs.com/liulun/p/3543777.html 监控方法 推荐使用windows自带的“性能监视器”(老版本的windows叫性能计数器)来监控服务器的 ...

  6. FpSpread添加表头(列名)标注

    for (int j = 0; j < fp.ActiveSheetView.ColumnCount; j++) { fp.ActiveSheetView.ColumnHeader.Cells[ ...

  7. 为自己的Android应用添加广告

    平时也写了不少Android小应用,但是都是做练习之用,从来没有想过添加广告赚钱这一说. 个人是非常反感在应用内添加广告这种行为的,非常影响用户体验,不小心点到广告的话,手机流量哗哗地就没了··· 但 ...

  8. AngularJs练习Demo1

    @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...

  9. 找不到类型“IBatisService.boxManageService”,它在 ServiceHost 指令中提供为 Service 特性值,或在配置元素 system.serviceModel/serviceHostingEnvironment/serviceActivations 中提供。

    找不到类型“IBatisService.boxManageService”,它在 ServiceHost 指令中提供为 Service 特性值,或在配置元素 system.serviceModel/s ...

  10. Java中list<Object>集合去重实例

    一:Java中list去重的方法很多,下面说一下其中一种方法:把list里的对象遍历一遍,用list.contain(),如果不存在就放入到另外一个list集合中: 二:实例 这里需要注意的是:使用c ...