公网穿透和RTC

RTC

RTC 是 Real-Time Communication 的简写,正如其中文名称 “即时通讯” 的意思一样,RTC 协议被广泛用于各种即时通讯领域,诸如:

  • 在线教育;
  • 直播中的主播连麦 PK;
  • 日常生活的音视频电话;
  • ......

WebRTC 则是 Google 基于 RTC 协议实现的一个开源项目,为 Web 页面提供了实时音视频传输所需的能力(前端部分);

RTC 有一个非常重要的特性,它是一个支持点对点直接传输的 P2P 协议;

P2P

P2P 是 “Peer to Peer” 的简写,在金融领域大家应该都听过这个名词(P2P 暴雷),金融中 P2P 可以指代 “个人对个人的网络放贷”;在互联网中也有着类似的意思,表示数据 “点对点传输” ,指数据可以在两个互联网用户之间直接传输,无需服务器在中间进行转发;

举个例子:IM 聊天软件中有 A、B 两个正在聊天的用户,聊天过程中,用户 A 的文字信息是没办法直接通过网络发送给用户 B 的,而是需要一个服务器 S 在中间做转发,“A -> S -> B”;但采用 RTC 协议的视频电话就不一样了,电话的音视频数据可以通过网络直接在两个用户之间传输,无需中间服务器进行转发:“A -> B”;

采用 RTC 协议能带来两个非常大的优势:

  • 大幅度降低服务端的负载,减少成本;
  • 用户间直接进行数据传输,延迟上能带来不小的提升;

NAT “墙”

从上文知道,RTC 是一个 P2P 协议,数据可以直接在用户之间传输;但现实往往比理论来的复杂,实际用户的网络环境并没有那么简单,如果不做一些特殊处理,数据很大概率无法在两个用户之间传输,之所以无法直接传输,为了大家更好的理解需要从头说起;

随着互联网的用户逐年增多,接入互联网的设备也越来越多,公网 IPv4 的地址池慢慢见底,新接入互联网的设备很难再分配到单独公网的 IPv4 地址,为了解决这个问题,引入了一个叫 NAT(Network address translation)的协议;新接入的设备不再直接分配公网的 IPv4 地址,而是躲在 NAT 设备(路由器等)之后,NAT 会给后面的每一个设备都分配一个单独的内网地址,NAT 内部将维护一个内外网的地址映射表格,举个例子:

NAT 设备会修改发出去和收到的数据包,比如把上面 “192.168.0.1:8088” 发出去的包改成 “220.181.38.149:1111” ,这样外部的设备就会以为自己是在跟 “220.181.38.149:1111” 通信,接收到响应包之后,NAT 会把目标地址 “220.181.38.149:1111” 修改为 “192.168.0.1:8088”,随后转发到内网;这样就实现了一个公网的 IPv4 地址给多个设备共同使用的效果;

NAT 在实现上述功能之后,为了内网设备不被攻击,还使用了两个安全策略:

  • NAT 超时:NAT 维护的内外网地址映射表存在超时时间,一段时间内没有数据传输,对应的映射就会被取消,造成连接链路中断;
  • NAT 墙:NAT 还实现了类似防火墙的能力,外部主动发送给内部设备的数据包到了 NAT 之后可能会被丢弃;

根据 NAT 墙策略的不同,最常见的 NAT 可以分为四种:

  1. Full Cone NAT(完全锥形):表示映射表中所有的地址,外网设备都可以直接访问到,是最宽松的策略了;
  2. Restricted Cone NAT(IP 限制锥形):没被访问过的外网地址发的数据包都会被丢弃,用上面的例子来解释,假如 “192.168.0.1:8088” 访问过外网 “103.15.99.89:80” 这个地址,那外网 “103.15.99.89” 这个 IP 的所有端口都将可以访问通内网,但其他外网地址的访问会被阻止;
  3. Port Restricted Cone NAT(端口限制锥形):类似 2,不过除了限制外网的 IP 地址外还会限制端口;
  4. Symmetric NAT(对称形):这种 NAT 的丢包策略和 3 一样,只要外网的 IP 和端口有一个没被访问过,数据包就会被丢弃;但是该类型的 NAT 内外网地址映射的策略不一样,对称型 NAT 不会直接给一个内网设备分配固定的 IP 和端口,而是根据访问的外网地址分配不同的 IP 和端口;举个例子,假设内网设备 A 访问外网 B 时的映射为 “192.168.0.1:8088 <--> 220.181.38.149:1111”,那么内网 A 访问外网 C 时的映射可能会变成 “192.168.0.1:8088 <--> 220.181.38.149:2222”;

为什么要叫锥形和对称形?

所谓锥形,是指本地端访问所有外网单元时都使用同样的公网IP和端口;例如,

本端 220.181.38.149:2222 --------  抖音

本端 220.181.38.149:2222 --------  王者荣耀

本端 220.181.38.149:2222 --------  小红书

而对称形,是指本地端访问不同外网单元时使用不同的公网IP和端口;例如:

本端 220.181.38.149:1111 --------  抖音

本端 220.181.38.149:2222 --------  王者荣耀

本端 220.181.38.149:3333 --------  小红书

ICE -- NAT “打洞”

知道 NAT 的存在之后,再举一个例子 :用户 A 知道用户 B 的网络地址,并且 A 和 B 在不同的 NAT 之后;某一时刻 A 想主动联系 B,然后 A 经过自己 NAT 发一个请求给 B,请求到达 B 的 NAT 时,因为 B 没联系过 A,所以 B 的 NAT 便会将 A 的请求丢弃;

上面简单的例子就可以看出,虽然 RTC 是一个 P2P 的协议,但因为 NAT 墙的存在,就算通讯的双方知道对方的网络地址,也没办法直接沟通......

所以,需要引入一个机制对这个沟通过程进行协调,帮助通讯双方能够越过 NAT 并成功建立连接,这套机制就是 ICE(Interactive Connectivity Establishment),ICE 是一个框架协议,可以让互联网中两个设备进行点对点的连接,ICE 框架包含的两个主要工具协议:

  • STUN
  • TURN

STUN

STUN(Session Traversal Utilities for NAT)是一个工具协议,这个协议的主要目的是协调帮助两个在 NAT 之后的设备建立 UDP (也可以是 TCP)传输;既然 STUN 是一个协议,那我们就可以采用任意技术栈来开发实现一个 STUN 服务及 STUN 客户端,实现的 STUN 主要有两个作用:

  1. 帮助获取客户端的公网地址,并通过复杂的策略,探测出客户端所处的 NAT 类型;
  2. STUN 还可以帮助两个客户端之间进行 NAT “打洞”或者协调 TURN 在两个客户端中间充当中继服务;

NAT 探测

服务端可以非常轻松的在数据包中获取请求的来源 IP 和端口,但是并没有办法知道对应的请求是客户端直发还是 NAT 转发的,更没办法知道是哪种类型的 NAT,客户端也一样无法知道自己的 NAT 情况;但只要 STUN 客户端及 STUN 服务齐心协力,就可以一步步探测出 NAT 情况;

STUN 服务和 STUN 客户端会按照下面的逻辑进行配合,一步步探测客户端所处的 NAT 情况;

ps:一个 STUN 服务需要拥有两个 IP ,通过两个 IP 的服务互相配合来探测 NAT 的情况
  1. 第一步,判断是否存在 NAT,客户端主动发一个请求到 STUN 服务的 “IP1 端口 1” 上,STUN 服务把收到的请求的 IP 和端口直接返回给客户端,客户端会将 STUN 服务返回的 IP 和端口跟自己的 IP 和端口进行比较,
    1. 如果一致,则表明客户端处在公网中,或者说客户端没有在 NAT 之后;(可建立host类型连接)
    2. 如果不一致,则表明客户端处在 NAT 之后,需要往下走继续探测 NAT 类型;
  2. 第二步,判断 NAT 是不是 Full Cone NAT(完全锥形),客户端发送请求到 STUN 服务的 “IP1 端口 1”,STUN 服务收到请求之后用 “IP2 端口 2” 主动往客户端发送一个请求,
    1. 如果客户端能够收到 STUN 服务 IP2 的请求,则表明 NAT 策略非常宽松来者不拒,是完全锥形;(可建立srflx类型的连接)
    2. 如果客户端没办法收到 STUN 服务 IP2 的请求,则数据包被 NAT 丢弃了,NAT 不是完全锥形,需要往下走继续探测 NAT 类型;
  3. 第三步,判断 NAT 是不是 Symmetric NAT(对称形),客户端主动往 STUN 服务的 “IP2 端口 2” 发送请求,STUN 服务收到请求之后把请求的来源 IP 和端口直接返回给客户端,客户端用收到的 IP 和端口跟 “第一步” 中的 IP 和端口进行比较,
    1. 如果两次收到的端口不一致,则表明 NAT 是对称形的;
    2. 如果一致,则表明 NAT 不是对称形的,需要进一步探测 NAT 类型;
  4. 第四步,判断 NAT 对端口的限制,客户端主动往 STUN 服务的 “IP2 端口 2” 发请求,要求 STUN 服务用 “IP2 端口 3” 往客户端发请求,
    1. 如果客户端收到了 “IP2 端口 3” 的请求,则表明 NAT 没有对端口进行限制,是 Restricted Cone NAT(IP 限制锥形);(可建立prflx类型连接)
    2. 如果没收到请求,则表明 NAT 限制了端口,是 Port Restricted Cone NAT(端口限制锥形);

NAT “打洞”

经过上面四个步骤之后,便知道了客户端的公网地址以及所在的 NAT 情况,光知道 NAT 情况还没用,NAT 依旧会对请求进行拦截,STUN 还需要协调两个客户端对各自的 NAT 进行打洞,客户端才能穿越 NAT 完成连接建立,下面从简单到复杂举几个例子来说明 NAT 的打洞流程;

只有一方在 NAT 后

假设:客户端 A 和客户端 B 需要建立 P2P 连接,客户端 A 直接拥有一个公网 IP,而客户端 B 在 NAT 之后;

这种情况下如果客户端 A 直接与客户端 B 通信,通信将会失败,客户端 A 发送的数据包会被客户端 B 的 NAT 丢弃;此时,STUN 服务端便会进行协调,让客户端 B 主动先往客户端 A 发送数据包,客户端 B 的 NAT 便记录了客户端 A 的通信记录,客户端 A 后续便可以与客户端 B 进行通信了;

客户端 B 主动连接客户端 A ”这个过程就被形象的称为 “给客户端 B 的 NAT 打洞”;

双方都在非对称形 NAT 后

假设:客户端 A 和客户端 B 需要建立 P2P 连接,客户端 A 和客户端 B 在不同的 NAT 之后;

这种情况下客户端 A 和客户端 B 往对方发送的数据都会被 NAT 丢弃,STUN 服务便会协调两个客户端,让它们先主动都往对方发送数据,在自己的 NAT 上留下对方的 “洞”,后续两个客户端便可以完成连接的建立了;

双方在对称形 NAT 后

假设:客户端 A 和 B 的 NAT 均为 Symmetric NAT(对称形);

这种情况下,先说结论,STUN 服务将无法协调客户端 B 的 NAT 打洞;

由于对称形 NAT 的特性,STUN 服务端看到的客户端 A “ip 、 端口”,将会和客户端 B 看到的客户端 A 的 “ip、 端口” 不一样,此时如果 STUN 服务强行协调客户端 B 给 NAT 进行打洞,打的洞客户端 A 并没办法使用;

所以这种情况下是没有办法建立 P2P 连接的,也因为这种情况的存在,才引入了 TURN 中继协议;

TURN

TURN 全称 “Traversal Using Relays around NAT(TURN):Relay Extensions to Session Traversal Utilities for NAT(STUN)” ,从全称就可以看出,TURN 是 STUN 的一个补充协议,当 STUN 无法完成两个客户端的 P2P 直连时,TURN 便会充当一个 “中继服务器”的角色,对两个客户端之间的信息进行转发;

如何快速判断是否能打洞?

给 NAT 类型进行一个排序,从宽松到严格的顺序如下:

  1. Full Cone NAT(完全锥形)
  2. Restricted Cone NAT(IP 限制锥形)
  3. Port Restricted Cone NAT(端口限制锥形)
  4. Symmetric NAT(对称形)

如果两个客户端的 NAT 类型的序号相加大于等于 7 ,则无法打洞成功,需要引入 TURN 服务;举个例子,如果两个客户端分别是 “4. Symmetric NAT(对称形)” 和 “2. Restricted Cone NAT(IP 限制锥形)”,则这两个客户端能打洞成功,因为他们的序号相加为 6 ,小于 7;

webRTC ICE

WebRTC建立网络连接的过程,主要包括收集candidate、交换candidate和按优先级尝试连接,该过程被称为ICE(Interactive Connectivity Establishment,交互式连接建立)。其中每个 candidate 都包含IP地址、端口、传输协议、类型等信息。

根据 RFC5245 协议 ,WebRTC将 candidate分为了四个类型:host、srflx、prflx、relay,它们的优先级依次降低。

host:Host Candidate,根据主机的网卡数量决定,一般一个网卡对应一个ip地址,然后给每个ip随机分配一个端口生成;这种类型的连接里,使用的是本机物理网卡的IP和端口。

srflx:Server Reflexive Candidate,根据STUN服务器获得的ip和端口生成;这种类型的连接里,使用的是STUN服务器映射的IP和端口;

prflx:Peer Reflexive Candidate,根据对端的ip和端口生成;这种类型的连接里,使用的是NAT上分配的IP和端口;

relay:Relayed Candidate,根据TURN服务器获得的ip和端口生成;这种类型的连接里,使用的是TURN服务器中继的IP和端口;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/207421.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【开源】基于Vue+SpringBoot的服装店库存管理系统

项目编号&#xff1a; S 052 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S052&#xff0c;文末获取源码。} 项目编号&#xff1a;S052&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 角色管理模块2.3 服…

Ubuntu镜像与K8S冲突,容器持续Terminating

问题 记录一次软件冲突BUG&#xff1a; eclipse-temurin:11-jdk&#xff08;底层Ubuntu 20.04.3 LTS&#xff09;镜像创建的容器在K8S-1.25.5上无法正常terminating&#xff0c;造成资源浪费&#xff0c;甚至引发K8S资源CPU insufficient报错。具体表现 某些容器镜像在K8S上无…

九章量子计算机:探索量子世界的革命性工具

九章量子计算机:探索量子世界的革命性工具 一、引言 九章量子计算机的推出,是近年来科技界最为引人瞩目的成就之一。这款基于量子力学的计算机,以其独特的计算方式和潜在的应用前景,引发了全球范围内的关注和讨论。本文将深入探讨九章量子计算机的原理、技术特点、应用前景…

【工具分享】| 阅读论文神器 使用技巧 AI润色 AI翻译

文章目录 1 使用技巧1.1 功能一 即时翻译1.2 功能二 文献跳转1.3 功能三 多设备阅读1.4 功能四 小组讨论笔记共享1.5 功能五 个人文献管理 2 其他功能 超级喜欢Readpaper这一款论文阅读软件&#xff0c;吹爆他哈哈 为什么&#xff1f; 当然是他可以解决我们传统阅读论文的种种…

python之pyqt专栏5-信号与槽1

在上一篇文章&#xff0c;我们了解到如果想要用代码改变QLabel的文本内容&#xff0c;可以调用QLabel类的text()函数。 但是现在有个这样的需求&#xff0c;界面中有一个Button与一个Label&#xff0c;当点击Button时&#xff0c;将Label的内容改变为“Hello world&#xff01;…

前端:实现div的隐藏与显示

效果 完整代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-widt…

云计算如何创芯:“逆向工作法”的性感之处

在整个云计算领域&#xff0c;能让芯片规模化的用起来&#xff0c;是决定造芯是否成功的天花板。在拉斯维加斯的亚马逊云科技2023 re:Invent则是完美诠释了这一论调。 亚马逊云科技2023 re:Invent开幕前两个小时&#xff0c;有一场小型的欢迎晚宴&#xff0c;《星期日泰晤士报》…

开源与闭源

我的观点&#xff1a; 开源与闭源软件都有各自的优势和劣势&#xff0c;没有绝对的对错之分。.. 一、开源和闭源的优劣势比较 开源的好处与劣处 优势&#xff1a; 创新与合作&#xff1a;开源软件能够吸引更多的开发者参与到项目中来&#xff0c;促进创新和合作。开放的源代码…

【小布_ORACLE笔记】Part11-1--RMAN Backups

Oracle的数据备份于恢复RMAN Backups 学习第11章需要掌握&#xff1a; 一.RMAN的备份类型 二.使用backup命令创建备份集 三.创建备份文件 四.备份归档日志文件 五.使用RMAN的copy命令创建镜像拷贝 文章目录 Oracle的数据备份于恢复RMAN Backups1.RMAN Backup Concepts&#x…

[PyTorch][chapter 64][强化学习-DQN]

前言&#xff1a; DQN 就是结合了深度学习和强化学习的一种算法&#xff0c;最初是 DeepMind 在 NIPS 2013年提出&#xff0c;它的核心利润包括马尔科夫决策链以及贝尔曼公式。 Q-learning的核心在于Q表格&#xff0c;通过建立Q表格来为行动提供指引&#xff0c;但这适用于状态…

社区便利店销售微信APP的设计与实现

摘 要 社区便利店销售小程序采用的技术&#xff1a;第一是Mysql数据库&#xff1b;第二是java程序开发语言&#xff1b;第三是ssm框架&#xff1b;第四是B/S结构。系统主要分为管理员、商家、用户三部分&#xff0c;这个销售小程序的功能有首页和个人中心&#xff0c;同时还有…

计算机毕业设计|基于SpringBoot+MyBatis框架健身房管理系统的设计与实现

计算机毕业设计|基于SpringBootMyBatis框架的健身房管理系统的设计与实现 摘 要:本文基于Spring Boot和MyBatis框架&#xff0c;设计并实现了一款综合功能强大的健身房管理系统。该系统涵盖了会员卡查询、会员管理、员工管理、器材管理以及课程管理等核心功能&#xff0c;并且…

MySQL 教程 1.4

MySQL 连接 使用mysql二进制方式连接 您可以使用MySQL二进制方式进入到mysql命令提示符下来连接MySQL数据库。 实例 以下是从命令行中连接mysql服务器的简单实例&#xff1a; [roothost]# mysql -u root -p Enter password:****** 在登录成功后会出现 mysql> 命令提示窗…

Android11编译第八弹:root用户密码设置

问题&#xff1a;user版本增加su 指令以后&#xff0c;允许切换root用户&#xff0c;但是&#xff0c;root用户默认没有设置密码&#xff0c;这样访问不安全。 需要增加root用户密码。 一、Linux账户管理 1.1 文件和权限 Linux一切皆文件。文件和目录都有相应的权限&#x…

微信小程序踩坑记录

一、引言 作者在开发微信小程序《目的地到了》的过程中遇到过许多问题&#xff0c;这里讲讲一些技术和经验问题。 基本目录机构&#xff1a; 二、问题 1、定位使用 获取定位一定要在app.json里面申明&#xff0c;不然是没办法获取定位信息的 "requiredPrivateInfos"…

jetson nano SSH远程连接(使用MobaXterm)

文章目录 SSH远程连接1.SSH介绍2.准备工作3.连接步骤3.1 IP查询3.2 新建会话和连接 SSH远程连接 本节课的实现&#xff0c;需要将Jetson Nano和电脑保持在同一个局域网内&#xff0c;也就是连接同一个路 由器&#xff0c;通过SSH的方式来实现远程登陆。 1.SSH介绍 SSH是一种网…

腾讯云最新优惠券领取入口,总面值2000元代金券,新用户、老用户、企业用户均可领取!

腾讯云推出年末感恩回馈活动&#xff0c;新老用户可免费领取总面值2000元的代金券礼包&#xff0c;适用于多种预付费产品&#xff0c;最高可抵扣36个月订单&#xff0c;领取后30天内有效。 领取入口&#xff1a; https://curl.qcloud.com/UpmL4ho3 领取说明&#xff1a; 腾…

制作太阳能小车

今天偶然星期想搞一个太阳能小车耍一下子&#xff0c;那么接下来就介绍下相关的准备物品吧 首先介绍下需要准备的物品&#xff1a; 1、玩具车拆下四个轮子 2、小马达一个 3、1.5v太阳能板&#xff08;根据自己的需求购买相应的电压1.5v 3.7v 5v 12v等等&#xff09; 4、3D打…

11.28~11.29基本二叉树的性质、定义、复习;排序算法;堆

完全二叉树&#xff08;Complete Binary Tree&#xff09;是一种特殊的二叉树结构&#xff0c;它具有以下特点&#xff1a; 所有的叶子节点都集中在树的最后两层&#xff1b;最后一层的叶子节点都靠左排列&#xff1b;除了最后一层&#xff0c;其他层的节点数都达到最大值。 …

Python 进阶(十二):随机数(random 模块)

《Python入门核心技术》专栏总目录・点这里 文章目录 1. 导入random库2. 常用随机数函数2.1 生成随机浮点数2.2 生成随机整数2.3 从序列中随机选择2.4 随机打乱序列3. 设置随机数种子4. 应用实例4.1 游戏开发4.2 数据分析4.3 加密与安全4.4 模拟实验