您的位置:首页 > 娱乐 > 明星 > 网站内容如何优化_百度seo排名点击_指数是什么_河北网站推广

网站内容如何优化_百度seo排名点击_指数是什么_河北网站推广

2025/6/6 10:57:30 来源:https://blog.csdn.net/Poisx/article/details/146636291  浏览:    关键词:网站内容如何优化_百度seo排名点击_指数是什么_河北网站推广
网站内容如何优化_百度seo排名点击_指数是什么_河北网站推广

WebRTC的ICE之TURN协议的交互流程和中继转发Relay媒体数据的turnserver的测试

WebRTC的ICE之TURN协议的交互流程中继转发Relay媒体数据的turnserver的测试

  • WebRTC的ICE之TURN协议的交互流程和中继转发Relay媒体数据的turnserver的测试
  • 前言
  • 一、TURN协议
    • 1、连接Turn Server 流程
      • ① 抓包交换流程图
      • ② TURN协议格式解析
        • 协议基础与消息结构
        • 关键方法类型
        • 核心属性类型
        • 错误码与状态‌
        • 数据传输机制‌
      • ③ 发送Allocate Request UDP 信息包信息
        • 再次发送 Allocate Request UDP 包 带上 协议、用户名和sha-1(user:realm:paasword)签名
      • ④ 发送CreatePermission Request
      • 发送数据Send Indication
      • 接收 Data Indiaction
      • ⑤ Channel-Bind Request
        • 发送数据 ChannelData Message
    • 2、 TURN测试Demo
    • 二 、 iceCandidate收集的时机有两种
      • 1、创建PeerConnection对象传入的参数ice_candidate_pool_size大于0会创建连接池的个数, 如果没有不会创建连接池ICE的速度就会有点慢
      • 2、 设置sdp时获取 iceCandidate
  • 总结


前言

TURN协议:文档RFC5766

文档中TURN协议工作原理图

                                     Peer AServer-Reflexive    +---------+Transport Address   |         |192.0.2.150:32102   |         ||              /|         |TURN              |            / ^|  Peer A |Client's              Server            |           /  ||         |Host Transport        Transport         |         //   ||         |Address               Address           |       //     |+---------+10.1.1.2:49721       192.0.2.15:3478     |+-+  //     Peer A|               |               ||N| /       Host Transport|   +-+         |               ||A|/        Address|   | |         |               v|T|     192.168.100.2:49582|   | |         |               /+-++---------+|   | |         |+---------+   /              +---------+|         ||   |N|         ||         | //               |         || TURN    |v   | |         v| TURN    |/                 |         || Client  |----|A|----------| Server  |------------------|  Peer B ||         |    | |^         |         |^                ^|         ||         |    |T||         |         ||                ||         |+---------+    | ||         +---------+|                |+---------+| ||                    |                || ||                    |                |+-+|                    |                ||                    |                ||                    |                |Client's                   |            Peer BServer-Reflexive    Relayed             TransportTransport Address   Transport Address   Address192.0.2.1:7000      192.0.2.15:50000     192.0.2.210:49191

WebRTC中走中继Relay 调用流程图

在这里插入图片描述

一、TURN协议

TURN                                 TURN           Peer          Peerclient                               server          A             B|-- Allocate request --------------->|             |             ||                                    |             |             ||<--------------- Allocate failure --|             |             ||                 (401 Unauthorized) |             |             ||                                    |             |             ||-- Allocate request --------------->|             |             ||                                    |             |             ||<---------- Allocate success resp --|             |             ||            (192.0.2.15:50000)      |             |             |//                                   //            //            //|                                    |             |             ||-- Refresh request ---------------->|             |             ||                                    |             |             ||<----------- Refresh success resp --|             |             ||                                    |             |             |
TURN                                 TURN           Peer          Peerclient                               server          A             B|                                    |             |             ||-- CreatePermission req (Peer A) -->|             |             ||<-- CreatePermission success resp --|             |             ||                                    |             |             ||--- Send ind (Peer A)-------------->|             |             ||                                    |=== data ===>|             ||                                    |             |             ||                                    |<== data ====|             ||<-------------- Data ind (Peer A) --|             |             ||                                    |             |             ||                                    |             |             ||--- Send ind (Peer B)-------------->|             |             ||                                    | dropped     |             ||                                    |             |             ||                                    |<== data ==================||                            dropped |             |             ||                                    |             |             |
--------------------------------------------------------------------------------------

TURN                                 TURN           Peer          Peerclient                               server          A             B|                                    |             |             ||-- ChannelBind req ---------------->|             |             || (Peer A to 0x4001)                 |             |             ||                                    |             |             ||<---------- ChannelBind succ resp --|             |             ||                                    |             |             ||-- [0x4001] data ------------------>|             |             ||                                    |=== data ===>|             ||                                    |             |             ||                                    |<== data ====|             ||<------------------ [0x4001] data --|             |             ||                                    |             |             ||--- Send ind (Peer A)-------------->|             |             ||                                    |=== data ===>|             ||                                    |             |             ||                                    |<== data ====|             ||<------------------ [0x4001] data --|             |             ||                                    |             |             |Figure 4

1、连接Turn Server 流程

和国标gb28181的协议差不多 都是先发送一包AllocateRequest到服务返回一个错误码然后在发送一个AllocateRequest请求带上 用户名和密码 然后Trunserver返回映射turn上ip地址和port端口

在这里插入图片描述

① 抓包交换流程图

在这里插入图片描述

② TURN协议格式解析

协议基础与消息结构

TURN协议基于STUN协议扩展,采用STUN消息格式(头部+属性列表),同时新增了专用于中继功能的方法和属性‌

  1. 消息头(Header):
  • Class‌:固定为0x00(请求)或0x10(指示消息)‌

  • Method‌:定义操作类型(如Allocate、ChannelBind等)‌

  • Length‌:消息总长度(不含头部)‌

  • Transaction ID‌:16字节唯一标识符,用于匹配请求与响应‌

‌2. 属性列表(Attribute)‌:

  • 每个属性由Type(2字节)、Length(2字节)和Value(可变长)组成‌

  • 例如:XOR-RELAYED-ADDRESS表示中继地址,CHANNEL-NUMBER标识信道号‌

关键方法类型

TURN协议新增以下STUN方法

  • Allocate‌:客户端向服务器申请中继地址,响应中包含XOR-RELAYED-ADDRESS属性‌
  • Refresh‌:延长中继地址的生命周期(通过LIFETIME属性设置超时时间)‌
  • ChannelBind‌:绑定信道号(CHANNEL-NUMBER)与特定Peer地址,启用ChannelData传输‌
  • Send/Data Indication‌:用于中继数据传输(Send为客户端→服务器,Data为服务器→客户端
核心属性类型

新增属性包括:

  • XOR-RELAYED-ADDRESS‌:服务器分配的中继地址(IP+端口),用于标识客户端的中继端点‌
  • XOR-MAPPRE-ADDRES: 本机映射外网地址(IP+port)
  • CHANNEL-NUMBER‌:2字节信道号(范围0x4000-0x7FFF),用于ChannelData报文的高效传输‌
  • LIFETIME‌:中继地址有效期(默认10分钟),客户端需定期刷新‌
  • DONT-FRAGMENT‌:标志位,指示客户端支持IP分片重组‌
错误码与状态‌

TURN协议扩展了STUN错误码:

  • 401(未认证)‌:请求未携带有效凭证,需重新发送认证信息‌78‌
  • 437(Allocation Mismatch)‌:客户端尝试使用未分配的信道或地址‌
  • 508(Insufficient Capacity)‌:服务器资源不足,无法分配中继地址‌
数据传输机制‌

1‌. Send/Data Indication‌:

  • 使用STUN消息格式,Send携带应用数据发送至服务器,Data由服务器转发至Peer‌
  • 头部包含XOR-PEER-ADDRESS属性,标识目标Peer地址‌67。
  1. ChannelData消息‌:
  • 非STUN格式,头部仅4字节(信道号+数据长度),减少传输开销‌
  • 需通过ChannelBind预先绑定信道号与Peer地址‌

③ 发送Allocate Request UDP 信息包信息

在这里插入图片描述

第一次返回 401 Unauthorized 信息 带有NONE(新生成的一次性随机数),REALM(标识服务器或服务的域)
在这里插入图片描述

再次发送 Allocate Request UDP 包 带上 协议、用户名和sha-1(user:realm:paasword)签名

密码

TURN服务返回 本机映射外网地址和TURN服务分配中继地址、有效时间
在这里插入图片描述

④ 发送CreatePermission Request

在这里插入图片描述
返回数据
在这里插入图片描述

发送数据Send Indication

!【】
在这里插入图片描述

接收 Data Indiaction

在这里插入图片描述

⑤ Channel-Bind Request

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fgithub.com%2Fchensongpoixs%2Fcturn_relay_demo&pos_id=img-B8Tiv02W-1743192961278)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fchensongpoixs.github.io%2F&pos_id=img-om16XyoI-1743192922198)
在这里插入图片描述

发送数据 ChannelData Message

在这里插入图片描述

2、 TURN测试Demo

TURN测试demo
在这里插入图片描述

二 、 iceCandidate收集的时机有两种

1、创建PeerConnection对象传入的参数ice_candidate_pool_size大于0会创建连接池的个数, 如果没有不会创建连接池ICE的速度就会有点慢

设置ice配置


bool Conductor::CreatePeerConnection(bool dtls) {RTC_DCHECK(peer_connection_factory_);RTC_DCHECK(!peer_connection_);RTC_LOG(LS_INFO) << __FUNCTION__;webrtc::PeerConnectionInterface::RTCConfiguration config;config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; //这个 config.enable_dtls_srtp = dtls; //是否加密webrtc::PeerConnectionInterface::IceServer server;server.uri = GetPeerConnectionString();config.ice_candidate_pool_size = 0; // 大于0 就在sdp之前进行stun和turn连接创建, 反之啥事情都不做server.username = user_name_;server.password = pass_word_;std::vector<std::string> turnservers;turnservers.push_back(turn_url_);server.urls = turnservers;// 设置走 turn server 进行转发媒体数据 哈config.type = webrtc::PeerConnectionInterface::kRelay;config.servers.push_back(server);peer_connection_ = peer_connection_factory_->CreatePeerConnection(config, nullptr, nullptr, this);return peer_connection_ != nullptr;
}

在CreatePeerConnection方法中

  1. 异步创建BasicPortAllocator对象中如果ice_candidate_pool_size大于在SetConfiguration方法中就会进行连接turn和stun服务
  2. 创建负责ICE管理类JsepTransportController
bool PortAllocator::SetConfiguration(const ServerAddresses& stun_servers,const std::vector<RelayServerConfig>& turn_servers,int candidate_pool_size,bool prune_turn_ports,webrtc::TurnCustomizer* turn_customizer,const absl::optional<int>& stun_candidate_keepalive_interval) 
{CheckRunOnValidThreadIfInitialized();// A positive candidate pool size would lead to the creation of a pooled// allocator session and starting getting ports, which we should only do on// the network thread.RTC_DCHECK(candidate_pool_size == 0 || thread_checker_.IsCurrent());bool ice_servers_changed = (stun_servers != stun_servers_ || turn_servers != turn_servers_);stun_servers_ = stun_servers;turn_servers_ = turn_servers;prune_turn_ports_ = prune_turn_ports;if (candidate_pool_frozen_) {if (candidate_pool_size != candidate_pool_size_) {RTC_LOG(LS_ERROR) << "Trying to change candidate pool size after pool was frozen.";return false;}return true;}if (candidate_pool_size < 0) {RTC_LOG(LS_ERROR) << "Can't set negative pool size.";return false;}candidate_pool_size_ = candidate_pool_size;// If ICE servers changed, throw away any existing pooled sessions and create// new ones.///// 20250328 ice[stun、turn]信息改变 就清除当前端口连接池会话if (ice_servers_changed) {pooled_sessions_.clear();}turn_customizer_ = turn_customizer;// If |candidate_pool_size_| is less than the number of pooled sessions, get// rid of the extras.while (candidate_pool_size_ < static_cast<int>(pooled_sessions_.size())) {pooled_sessions_.back().reset(nullptr);pooled_sessions_.pop_back();}///// |stun_candidate_keepalive_interval_| will be used in STUN port allocation// in future sessions. We also update the ready ports in the pooled sessions.// Ports in sessions that are taken and owned by P2PTransportChannel will be// updated there via IceConfig.// ICE的心跳包  的stun_candidate_keepalive_interval_ = stun_candidate_keepalive_interval;for (const auto& session : pooled_sessions_) {session->SetStunKeepaliveIntervalForReadyPorts(stun_candidate_keepalive_interval_);}// If |candidate_pool_size_| is greater than the number of pooled sessions,// create new sessions.while (static_cast<int>(pooled_sessions_.size()) < candidate_pool_size_) {IceParameters iceCredentials = IceCredentialsIterator::CreateRandomIceCredentials();PortAllocatorSession* pooled_session = CreateSessionInternal("", 0, iceCredentials.ufrag, iceCredentials.pwd);pooled_session->set_pooled(true);//20250327  触发MSG_CONFIG_START信号   探测stun和turn 服务连通性 pooled_session->StartGettingPorts();pooled_sessions_.push_back(std::unique_ptr<PortAllocatorSession>(pooled_session));}return true;
}

2、 设置sdp时获取 iceCandidate

整体调用流程

在这里插入图片描述

调用流程图
在这里插入图片描述


bool TurnPort::HandleIncomingPacket(rtc::AsyncPacketSocket* socket,const char* data,size_t size,const rtc::SocketAddress& remote_addr,int64_t packet_time_us) {if (socket != socket_) {// The packet was received on a shared socket after we've allocated a new// socket for this TURN port.return false;}// This is to guard against a STUN response from previous server after// alternative server redirection. TODO(guoweis): add a unit test for this// race condition.if (remote_addr != server_address_.address) {RTC_LOG(LS_WARNING) << ToString()<< ": Discarding TURN message from unknown address: "<< remote_addr.ToString() << " server_address_: "<< server_address_.address.ToString();return false;}// The message must be at least the size of a channel header.if (size < TURN_CHANNEL_HEADER_SIZE) {RTC_LOG(LS_WARNING) << ToString()<< ": Received TURN message that was too short";return false;}if (state_ == STATE_DISCONNECTED) {RTC_LOG(LS_WARNING)<< ToString()<< ": Received TURN message while the TURN port is disconnected";return false;}// Check the message type, to see if is a Channel Data message.// The message will either be channel data, a TURN data indication, or// a response to a previous request.uint16_t msg_type = rtc::GetBE16(data);if (IsTurnChannelData(msg_type)) {HandleChannelData(msg_type, data, size, packet_time_us);return true;}if (msg_type == TURN_DATA_INDICATION) {HandleDataIndication(data, size, packet_time_us);return true;}if (SharedSocket() && (msg_type == STUN_BINDING_RESPONSE ||msg_type == STUN_BINDING_ERROR_RESPONSE)) {RTC_LOG(LS_VERBOSE)<< ToString()<< ": Ignoring STUN binding response message on shared socket.";return false;}// This must be a response for one of our requests.// Check success responses, but not errors, for MESSAGE-INTEGRITY.
#if TURN_LOGstd::cout << "[turn][hash()  = " << hash() << "]" << std::endl;RTC_LOG(LS_INFO) << "[turn][hash()  = " << hash() << "]";
#endif // #if TURN_LOGif (IsStunSuccessResponseType(msg_type) &&!StunMessage::ValidateMessageIntegrity(data, size, hash())) {RTC_LOG(LS_WARNING) << ToString()<< ": Received TURN message with invalid ""message integrity, msg_type: "<< msg_type;return true;}request_manager_.CheckResponse(data, size);return true;
}

总结

WebRTC源码分析地址:https://github.com/chensongpoixs/cwebrtc

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com