根据通信双方所处网络环境不同,点对点通信可以划分成以下三类:

i> 公网:公网

ii>公网:内网

iii>内网:内网

前两种容易实现,我们这里主要讨论第三种。

这其中会涉及到NAT和NAPT的概念,请大家预先浏览一下:https://en.wikipedia.org/wiki/Network_address_translation(NAT)。NAT目前主要依托于路由器实现:


其中cone NAT中分三种,它们在内外网ip:port的映射机制也不同:

内网 ip_i:port_i <--> NAT ip_o:port_o (相同的 内网 ip_i:port_i 无论访问哪个外部网址,在映射的生命周期内 NAT ip_o:port_o 不会改变)

Full: 所有发送到ip_o:port_o的消息都会转发到ip_i:port_i上

Restricted: 只有ip_i:port_i 访问过的 addr(不限制端口{host:any}),其发送到ip_o:port_o的消息才会转发到ip_i:port_i上

Port Restricted:只有ip_i:port_i 访问过的 addr(限制端口{host: port_o}),其发送到ip_o:port_o的消息才会转发到ip_i:port_i上

Sysmmetric NAT则与以上都不同:

每次内网ip_i:port_i 访问不同的addr(host不同或port不同,都算是不同地址)时,会映射到不同的 NAT ip_o:port_o

以上四种 NAPT 类型在p2p情况下(A and B)有 10 种组合方式,根据发起方不同可以扩展到 16种情况,这十六种情况中并不是每一种情况都能打洞成功的。现有网上的资料显示,内网:内网 情况下打洞都是需要打洞服务器进行引导的,打洞又分UDP和TCP两种情况,我们大致说一下打洞的流程:

假设 A 和 B 双方都是 cone 模式, 在 服务器 S 的引导下进行 TCP打洞

(1)A 和 B 向 S 通过 UDP 发送消息(S 可以从 UDP 消息提取出其公网 IP)

(2)A (ip_a_i, port_a_i) 向 S 建立 TCP 链接,发送与B 通讯的请求,同时 监听 (ip_a_i, port_a_i)

(3)S 提取出 A tcp 链接的公网地址(ip_a_o, port_a_o), 通过UDP协议向 B 发送(ip_a_o, port_a_o)

(4)B 向 (ip_a_o, port_a_o)发起TCP链接请求,如果失败则执行第5步,如果成功则到此为止

(5)B 保持内网地址(ip_b_i,port_b_i)不变向 S 发起TCP链接请求,通知其已经向A发送了链接请求,并监听(ip_b_i,port_b_i)

(6)S 提取出 B的tcp链接公网(ip_b_o, port_b_o), 通过UDP 将(ip_b_o, port_b_o)发送给A

(7) A 通过(ip_a_i, port_a_i)向 B发起链接请求

其中Sysmmetric :Sysmmetric 和 Sysmmetric:Port Restricted 这两种组合是没办法打洞的:
我们假设A是 Sysmmetric \ B 是 Port Restricted

《1》当 A 向 S 发起tcp链接的时候 假设形成 NAT 映射(192.168.1.4:8080 <--> 61.22.37.16:33956)

《2》S 将 61.22.37.16:33956 转发给 B ,B 向该地址发起链接请求

《3》B的路由器的路由表中会添加 61.22.37.16:33956 这个地址,如果A再次通过该地址来向B发起通信就可以完成通信

然而,当A向B发起访问的时候会形成一个新的 NAT 映射关系,产生一个新的公网地址,所以B不会接受其访问。反之如果A是 Port Restricted\ B是 Sysmmetric 也无法完成打洞,大家可以自己思考一下为什么。

p2p 打洞技术的更多相关文章

  1. [p2p]UDP用打洞技术穿透NAT的原理与实现

    首先先介绍一些基本概念:            NAT(Network Address             Translators),网络地址转换:网络地址转换是在IP地址日益缺乏的情况下产生的, ...

  2. P2P技术基础: 关于TCP打洞技术

    4 关于TCP打洞技术 建立穿越NAT设备的p2p的 TCP 连接只比UDP复杂一点点,TCP协议的“打洞”从协议层来看是与UDP的“打洞”过程非常相似的.尽管如此,基于TCP协议的打洞至今为止还没有 ...

  3. UDP 构建p2p打洞过程的实现原理(持续更新)

    UDP 构建p2p打洞过程的实现原理(持续更新) 发表于7个月前(2015-01-19 10:55)   阅读(433) | 评论(0) 8人收藏此文章, 我要收藏 赞0 8月22日珠海 OSC 源创 ...

  4. TCP打洞技术

    //转http://iamgyg.blog.163.com/blog/static/3822325720118202419740/ 建立穿越NAT设备的p2p的TCP连接仅仅比UDP复杂一点点,TCP ...

  5. NAT详解:基本原理、穿越技术(P2P打洞)、端口老化等

    这是一篇介绍NAT技术要点的精华文章,来自华3通信官方资料库,文中对NAT技术原理的介绍很全面也很权威,对网络应用的应用层开发人员而言有很高的参考价值. 学习交流 移动端即时通讯学习交流: 21589 ...

  6. 低延时的P2P HLS直播技术实践

    本文根据4月21日OSC源创会·武汉站的现场分享为蓝本,重新整理.以下是演讲内容: 近几年,随着直播.短视频等视频领域对带宽要求的提升以及CDN行业竞争的加剧,很多CDN公司开始往P2P-CDN方向发 ...

  7. 【Todo】UDP P2P打洞原理

    参考以下两篇文章: https://my.oschina.net/ososchina/blog/369206 http://m.blog.csdn.net/article/details?id=666 ...

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

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

  9. P2P通讯原理

    1.简介 当今互联网到处存在着一些中间件(MIddleBoxes),如NAT和防火墙,导致两个(不在同一内网)中的客户端无法直接通信.这些问题即便是到了IPV6时代也会存在,因为即使不需要NAT,但还 ...

随机推荐

  1. exportfs 入门/ 错误

    exportfs -uv 不能卸载, exportfs -au 才可以 ================================================================ ...

  2. C# 通过this关键字来扩展方法

    好处:不需要继承,对现有类型进行扩展 public static class ExtString { public static string myTest(this String str) { re ...

  3. java浮点类型计算

    java浮点类型需要采用java.math.*这个工具包,这样的计算结果才是我们想要的.呵呵 import java.math.BigDecimal; import java.text.NumberF ...

  4. python运维开发(二十五)---cmdb开发

    内容目录: 浅谈ITIL CMDB介绍 Django自定义用户认证 Restful 规范 资产管理功能开发 浅谈ITIL TIL即IT基础架构库(Information Technology Infr ...

  5. 简单天气应用开发——自定义TableView

    顺利解析JSON数据后,天气数据已经可以随意提取了,现在要做的就是建立一个简单的UI. 实况信息较为简单,几个Lable就可以解决.主要是七天天气预报有点麻烦,那是一个由七个字典构成的数组,需要提取出 ...

  6. 整数运算:CPU内部只有加法运算

    学汇编的一边儿去.我这里讲的是CPU进行计算的原理.首先我这里用MC的红石电路模拟了一个加法器:http://www.0xaa55.com/thread-313-1-1.htm首先加法器是怎么实现的呢 ...

  7. 分布式搜索ElasticSearch构建集群与简单搜索实例应用

    分布式搜索ElasticSearch构建集群与简单搜索实例应用 关于ElasticSearch不介绍了,直接说应用. 分布式ElasticSearch集群构建的方法. 1.通过在程序中创建一个嵌入es ...

  8. Nape实现坐标旋转角度回弹

    乒乓球以一个向量运动,碰到障碍后反弹以一个新的向量运动,如下图: 要实现回弹只需要求出向量v1,把向量v0取反,再旋转(a+b)度就可以得到向量v1. 向量取反: var v:vec2 = new V ...

  9. linux自动化构建工具-scons指南

    1.scons是linux下的自动构建工具 scons是用Python编写的,使用scons之前需确认是否已经安装了Python.(在系统的命令行中运行python -V或python --versi ...

  10. 关于JVM内存模型的一些总结

    首先上图,了解一下大概结构 1.程序计数器 程序计数器(Program Counter)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里,字节码解释器工 ...