TURN(Traversal Using Relays around NAT)协议是一个网络协议,旨在解决 NAT(网络地址转换)和防火墙 环境下的 UDP/TCP通信问题。它通常与 STUN 和 ICE 协议一起使用,广泛应用于 WebRTC、SIP 和视频会议等实时通信场景中。

为什么需要 TURN?

  1. NAT 问题

NAT 会屏蔽内网客户端的真实地址,使两个处于不同 NAT 环境的客户端 无法直接建立连接

  1. STUN 的局限

STUN 可以帮助客户端获取自己的公网 IP 和端口,但当:

  • 双方都在对称型 NAT 后面,
  • 或者存在严格的防火墙时,

STUN 穿透失败,这时就需要 TURN。

工作原理

TURN 的基本思想是:

通过中继服务器(TURN Server)转发媒体流量,绕过 NAT/防火墙。

工作流程

  • 阶段1:客户端与 TURN Server 建立连接(Allocate)

    • Step 1.1:客户端发起 Allocate 请求

      • 类型:Allocate Request
      • 内容:希望使用的传输协议(UDP/TCP)、Lifetime 等
      • 信令方式:基于 STUN over UDP/TCP
      Client A --> TURN Server
      Message: Allocate Request
      Attributes: REQUESTED-TRANSPORT=UDP
      
    • Step 1.2:TURN Server 分配中继地址

      • 返回:Allocate Success Response

      • 包含字段:XOR-RELAYED-ADDRESS(中继地址)、XOR-MAPPED-ADDRESS(客户端映射地址)

      TURN Server --> Client A
      Message: Allocate Success
      XOR-RELAYED-ADDRESS: 203.0.113.1:54320  ← 中继地址
      
  • 阶段2:建立 Permission(通信授权)

    为了安全,TURN Server 默认不允许所有对端通信,必须显式授权。

    • Step 2.1:CreatePermission 请求

      Client A --> TURN Server
      Message: CreatePermission
      XOR-PEER-ADDRESS: 对端 B 的公网地址
      
    • Step 2.2:成功响应

    • 若授权成功,返回 CreatePermission Success Response

    • 默认权限 300 秒失效

  • 阶段3:数据通道建立(Send Indication 或 ChannelBind)

​ TURN 支持两种数据通道:

通道方式描述性能
Send/Receive Indication使用完整 STUN 消息发送数据灵活,开销大
ChannelData映射通道编号,提高效率更快,推荐
  • Step 3.1:发送 ChannelBind 请求
Client A --> TURN Server
Message: ChannelBind
XOR-PEER-ADDRESS: Client B
CHANNEL-NUMBER: 0x4000-0x7FFF(客户端分配)
  • Step 3.2:TURN Server 回复成功绑定

    • 之后,Client A 可以通过 ChannelData 消息直接发送媒体数据。
  • 阶段4:媒体数据中继传输

    • A → B 流程
    Client A --> TURN Server
    Message: ChannelData 或 Send Indication
    
    TURN Server --> Client B
    Message: UDP/TCP 数据包
    
    • B → A 反向流

      Client B --> TURN Server(发往分配的 relayed address)
      TURN Server --> Client A(通过 Channel 或 Data Indication)
      
  • 阶段5:Refresh 保活

    • TURN allocation 默认 600秒过期

    • 客户端需周期性发送 Refresh Request 保活

      Client A --> TURN Server
      Message: Refresh Request
      LIFETIME: 600
      

流程时序图:

客户端A                             TURN服务器                             客户端B|                                    |                                      ||-------- Allocate Request --------->|                                      ||<------ Allocate Response ----------|                                      ||                                    |                                      ||--- CreatePermission (B的IP) ----->|                                      ||<--- CreatePermission Success ------|                                      ||                                    |                                      ||-------- ChannelBind (B的IP) ----->|                                      ||<----- ChannelBind Success ---------|                                      ||                                    |                                      ||---- ChannelData(B的数据) ------->|                                      ||                                    |-----> 转发数据到 客户端B ---------->||                                    |<----- 客户端B发来响应数据 -----------||<--- ChannelData(返回数据) -------|                                      ||                                    |                                      ||--------- Refresh Request --------->|                                      ||<-------- Refresh Response ---------|                                      |

TURN 与 STUN、ICE 的关系

协议作用
STUN获取公网地址,尝试打洞
TURN中继传输,保证连接
ICE综合使用 STUN/TURN,选择最优路径(直接连接优先)

TURN 是一种最后手段,因为它会增加 延迟带宽成本

协议详解

协议标准

TURN 协议定义在以下 RFC 中:

  • RFC 5766:TURN 协议标准
  • RFC 5389:STUN 基础
  • RFC 6062:支持 TCP 的 TURN
  • RFC 6156:IPv6 支持

通信流程详细图解

客户端A ---------> TURN服务器 <--------- 客户端BAllocate            Send IndicationRefresh             Data ChannelSend/Receive        Permissions

主要步骤:

  • Allocate Request:客户端请求分配中继地址;
  • Allocate Success Response:服务器返回一个公网 IP+端口(Relayed Address);
  • CreatePermission:允许某个对端向这个中继地址发送数据;
  • Send Indication / Data Indication:发送或接收数据;
  • Refresh:保持分配有效(每300秒刷新);
  • Channel Bind(可选):绑定 Channel,降低通信成本;

消息结构(基于 STUN)

TURN 消息与 STUN 类似,由以下字段组成:

  • Message Type:请求/响应/指示类型
  • Transaction ID:用于匹配请求与响应
  • Attributes
    • XOR-RELAYED-ADDRESS:返回的中继地址
    • LIFETIME:分配有效期
    • DATA:要中继的实际数据
    • XOR-PEER-ADDRESS:目标地址

TURN Server 实现

常见开源 TURN Server:

名称简介
Coturn最流行的 TURN server,支持 STUN、TURN、TLS 等协议
restund轻量级实现
rfc5766-turn-server老旧项目,已被 Coturn 替代

Coturn 配置文件示例:

listening-port=3478
relay-ip=your_public_ip
realm=yourdomain.com
user=username:password

优缺点

优点:

  • 100% 可达性:即使双方都在对称 NAT 后,也能通信;
  • 标准化:已被 WebRTC、SIP 等广泛采用;

缺点:

  • 服务器成本高:带宽开销大;
  • 延迟增加:所有流量都要绕行服务器;
  • 复杂度增加:协议较 STUN 更复杂;

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

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

相关文章

Python 的内置函数 hasattr

Python 内建函数列表 > Python 的内置函数 hasattr Python 的内置函数 hasattr() 用于检查一个对象是否具有指定的属性或方法。该函数的语法为&#xff1a; hasattr(object, name)参数说明&#xff1a; object&#xff1a;要检查的对象&#xff0c;可以是任何 Python 对象…

docker使用技巧之把扩展卷命名变成有意义

背景 之前使用别人的镜像之后&#xff0c;启动docker后发出现了一堆看不懂名称的扩展卷 eg&#xff1a;集群查看 扩展卷查看 这个时候如果有很多集群需要清理扩展卷就很麻烦&#xff0c;不知道是哪个集群的 操作步骤 可以实现的分析&#xff1a;这个扩展卷的信息应该是和…

《博物通书》《博物新编》与满清历史篡改

《博物新编》作为近代西方科技输入中国的首部著作&#xff0c;其问世犹如一颗投入平静湖面的巨石&#xff0c;在 19 世纪中期的中国激起层层涟漪&#xff0c;对中国近代科学发展产生了多维度、深层次的影响。它不仅是知识传播的载体&#xff0c;更是推动中国科学从传统走向近代…

【入门】【例18.1】 睡眠

| 时间限制&#xff1a;C/C 1000MS&#xff0c;其他语言 2000MS 内存限制&#xff1a;C/C 64MB&#xff0c;其他语言 128MB 难度&#xff1a;中等 分数&#xff1a;100 OI排行榜得分&#xff1a;12(0.1分数2难度) 出题人&#xff1a;root | 描述 一个人只有每天睡眠时间到达 8…

DAY 38 Dataset和Dataloader类

知识点回顾&#xff1a; Dataset类的__getitem__和__len__方法&#xff08;本质是python的特殊方法&#xff09;Dataloader类minist手写数据集的了解 作业&#xff1a;了解下cifar数据集&#xff0c;尝试获取其中一张图片 import torch import torch.nn as nn import torch.o…

【Kubernetes】以LOL的视角打开K8s

前言 对于大部分后端程序员乃至于非后端程序员来说&#xff0c;在当前的云原生时代&#xff0c;Kubernetes&#xff08;后称K8s&#xff09;都是绕不开的一项技术&#xff1b;同时&#xff0c;对于这个时代的程序员来说&#xff0c;“英雄联盟”&#xff08;后称LOL&#xff0…

UE5 游戏模板 —— FirstShootGame

UE5 游戏模板 —— FirstShootGame 前言一、GameMode二、组件1.ShooterPickUpComponent单播多播 2.ShooterWeaponComponent附着武器开火 3.小结4.ShooterProjectile初始化碰撞受击检测 三、Character初始化输入移动 总结 前言 有了前两个俯视角游戏的基础让我们来看看相对复杂…

国家级与省级(不含港澳台)标准地图服务网站汇总

在先前的文章中&#xff0c;介绍了部分省级的标准地图服务网站可以下载各个区县近几年、不同要素的标准地图&#xff08;链接&#xff1a;国家与省市县 标准地图服务网站 审图号地图下载&#xff09;&#xff0c;但是当时只汇总了部分省级的标准地图服务网站。 这两天看到了一个…

前端开发面试题总结-vue3框架篇(一)

文章目录 Vue3高频问答一、vue2/vue3中常用的构建工具和脚手架分别是什么? 有什么区别?二、请说一说vue2和vue3的区别&#xff1f;三、请说一说vue2和vue3响应式原理的区别&#xff1f;四、vue3 如何定义响应式数据?五、说一说你对vue3中的setup函数?六、说一说vue3中的路由…

【LLM06---相对位置编码】

文章目录 相对位置编码经典式XLNET式T5式DeBERTa式 相对位置编码 上一节我们介绍了绝对位置编码&#xff0c;这一节我们来看相对位置编码&#xff0c;也就是用相对位置信息来表示&#xff0c;之前每一个token的位置式通过一个绝对的位置向量来表示的&#xff0c;现在我们在计算…

纯跟踪算法本质解密:航向角偏差=预瞄角?数学证明与工程实践

定义关键问题 在深入纯跟踪算法核心前&#xff0c;必须澄清一对容易被混淆但至关重要的概念&#xff1a; 概念坐标系物理意义计算方式航向角偏差(α_global)全局坐标系车辆航向与预瞄点方向的夹角预瞄点方位角 - 车辆航向角预瞄角(α_body)车身坐标系预瞄点相对于车辆纵轴的夹…

自动驾驶叉车在仓库环境中是否安全?

随着自动驾驶叉车的兴起&#xff0c;仓库运营持续演进。叉车自动化技术的引入使仓库设施变得更快、更安全且更具成本效益。然而一个关键问题依然存在&#xff1a;它们在繁忙的仓库环境中是否安全&#xff1f; 一 、什么是自动驾驶叉车&#xff1f; 自动驾驶叉车&#xff0c;也…

Neo4j操作指南:修改节点数据与新增节点属性

Neo4j操作指南&#xff1a;修改节点数据与新增节点属性 引言 Neo4j作为领先的图数据库&#xff0c;提供了灵活的数据操作方式。在实际应用中&#xff0c;我们经常需要修改已有节点的数据或为节点添加新属性。本文将详细介绍如何使用Cypher查询语言在Neo4j中完成这些操作&…

AI大模型学习之基础数学:微积分在AI大模型中的核心-梯度与优化(梯度下降)详解

微积分在AI大模型中的核心:梯度与优化(梯度下降) 人工智能(AI)大模型的训练和优化依赖于数学基础,其中微积分、线性代数和概率统计构成了其理论核心。微积分在AI中的核心作用在于提供优化工具,尤其是通过梯度和梯度下降方法,帮助模型在高维参数空间中找到损失函数的最…

记录tweenjs踩坑

初次上手tweenjs&#xff0c;试了很多示例代码都不生效&#xff0c;结果在html中生效&#xff0c;在vue3的项目中怎么都不生效 <!DOCTYPE html> <html lang"en"><head><title>Tween.js / simplest possible example!</title><meta…

PINA开源程序用于高级建模的 Physics-Informed 神经网络

​一、软件介绍 文末提供程序和源码下载 PINA 是一个开源 Python 库&#xff0c;旨在简化和加速科学机器学习 &#xff08;SciML&#xff09; 解决方案的开发。PINA 基于 PyTorch、PyTorch Lightning 和 PyTorch Geometry 构建&#xff0c;提供了一个直观的框架&#xff0c;用…

一种对外IP/MAC地址收敛的软硬件系统

----------原创不易&#xff0c;欢迎点赞收藏。广交嵌入式开发的朋友&#xff0c;讨论技术和产品------------- 今天发一篇五年前的文章&#xff0c;不调单板。对以太网和交换片的较多理解&#xff0c;对系统级的优化。 大部分的网络设备&#xff0c;都由多种单板组成&#x…

【flink】 flink 读取debezium-json数据获取数据操作类型op/rowkind方法

flink 读取debezium-json数据获取数据操作类型op/rowkind方法。 op类型有c&#xff08;create&#xff09;,u&#xff08;update&#xff09;,d&#xff08;delete&#xff09; 参考官网案例&#xff1a;此处的"op": "u",就是操作类型。 {"before&qu…

某手游cocos2dlua反编译

一、获取加载的luac文件 通过frida hook libccos2dlua.so 的luaL_loadbuffer函数对luac进行dump js代码如下&#xff0c;得到dump后的lua文件 // 要加载的目标库名 var targetLibrary "libcocos2dlua.so"; var dlopen Module.findExportByName(null, "dlope…

`toRaw` 与 `markRaw`:Vue3 响应式系统的细粒度控制

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…