【音視頻】WebRTC ICE 模塊深度剖析

原文鏈接:
https://mp.weixin.qq.com/s?__biz=MzIzMjY3MjYyOA==&mid=2247498075&idx=2&sn=6021a2f60b1e7c71ce4d7af6df0b9b89&chksm=e893e540dfe46c56323322e780d41aec1f851925cfce8b76b3f4d5cfddaa9c7cbb03a7ae4c25&scene=178&cur_album_id=3146991347015499781#rd

一、WebRTC ICE

1.1 ICE 是什么?

在 WebRTC(網頁實時通信)技術體系中,ICE(Interactive Connectivity Establishment,交互式連接建立) 是解決 “設備間如何突破網絡壁壘(如 NAT 網關)建立直接通信” 的核心協議。它通過整合 STUN(會話穿越實用工具)TURN(中繼穿越實用工具),動態收集通信候選地址、檢查連通性,并最終選擇最優路徑(優先 P2P,失敗時降級為中繼),確保實時音視頻、數據傳輸的可靠性

1.2 為什么需要 ICE?

WebRTC 的目標是實現 “瀏覽器 / 終端設備間的直接通信(P2P)”,但現實網絡中存在兩大障礙:

  • IP 地址短缺:IPv4 地址耗盡導致絕大多數設備處于局域網內,僅擁有內網 IP(如 192.168.x.x、10.x.x.x),無法直接被公網設備訪問。
  • NAT 網關隔離:NAT(網絡地址轉換)是解決 IP 短缺的核心技術,但它會 “隱藏” 內網設備的真實地址,僅允許內網設備主動發起的外網連接,拒絕外部設備的主動訪問 —— 這直接阻斷了 P2P 通信的可能性。

ICE 的核心思想正是繞開 NAT 限制:通過收集設備的 “通信候選地址(Candidate)”,嘗試不同路徑的連通性,最終找到一條能讓兩端互通的路徑。

1.3 通信候選地址(Candidate)

ICE 為每個設備(稱為 “代理”)收集多種 Candidate 地址(IP + 端口 + 傳輸協議的組合,WebRTC 中默認用 UDP),每種 Candidate 對應一種潛在的通信路徑。核心類型如下:

Candidate 類型來源與作用適用場景
Host Candidate(本地候選)設備本地網卡的真實地址(如內網 IP 或公網 IP)兩端處于同一局域網(如辦公室內設備),或一端擁有公網 IP
Srflx Candidate(服務器反射候選)設備向 STUN 服務器發送請求,STUN 返回 NAT 網關的 “公網映射地址”(內網 IP 經 NAT 轉換后的公網地址)兩端均通過 圓錐型 NAT 接入公網,可通過反射地址實現 P2P 打洞
Prflx Candidate(對等反射候選)連通性檢查過程中,通過對端的 STUN Binding 請求 “動態發現” 的 NAT 反射地址補充 Srflx 覆蓋不到的場景(如對稱型 NAT 下的臨時映射地址)
Relay Candidate(中繼候選)設備向 TURN 服務器請求,由 TURN 分配的 “中繼地址”(所有數據通過 TURN 服務器轉發)P2P 打洞失敗時(如對稱型 NAT 間通信),降級為中繼傳輸
關鍵區分:Srflx 與 Prflx
  • Srflx 是通過 STUN 服務器主動獲取的,提前通過信令交換給對端;
  • Prflx 是在 連通性檢查階段動態發現的,無需提前交換,僅在檢查過程中生成。

1.4 STUN 與 TURN 協議

ICE 本身不直接 “穿越 NAT”,而是依賴 STUN 和 TURN 實現核心能力。二者分工明確:STUN 負責 “發現 NAT 映射地址” 和 “檢查連通性”,TURN 負責 “P2P 失敗時提供中繼”

STUN:NAT 地址發現與連通性檢查

STUN(Session Traversal Utilities for NAT)是一種輕量級協議,主要解決兩個問題:

  1. 獲取 NAT 公網映射地址:內網設備向 STUN 服務器發送 Binding Request,STUN 服務器返回設備的 “公網映射地址(MAPPED-ADDRESS)”,設備據此生成 Srflx Candidate。
  2. 驗證連通性:ICE 用 STUN 的 Binding Request/Response 檢查 “候選地址對(Candidate Pair)” 是否能互通(即 “打洞” 是否成功)。
(1)STUN 的版本演進:RFC3489 vs RFC5389

ICE 僅支持 RFC5389(現代 STUN),因為早期的 RFC3489(Classic STUN)存在諸多局限性:

特性RFC3489(Classic STUN)RFC5389(現代 STUN)
傳輸協議支持僅 UDP支持 UDP/TCP/TLS
安全認證支持短期 / 長期憑證認證
NAT 類型覆蓋不支持對稱型 NAT支持對稱型 NAT 檢測
IPv6 支持支持 IPv6
地址篡改防護提供 XOR-MAPPED-ADDRESS
(2)STUN 消息格式:20 字節頭 + 可變屬性

STUN 消息由 “固定頭部” 和 “可變屬性” 組成,結構如下:

在這里插入圖片描述

  • 關鍵頭部字段

    • 魔術字(Magic Cookie):固定值 0x2112A442,用于區分 STUN 消息與其他協議(如 RTP),并參與 XOR 地址計算。
    • 事務 ID(Transaction ID):96 位隨機值,用于關聯 “請求(Request)” 與 “響應(Response)”(避免多請求時混淆)。

ICE 核心擴展屬性(STUN 為 ICE 新增的關鍵屬性):

屬性名作用
PRIORITY標識 Candidate 的優先級,用于計算 Candidate Pair 的優先級(決定檢查順序)
USE-CANDIDATE提名 Candidate Pair 為 “可用路徑”,觸發后續 DTLS 加密連接建立
ICE-CONTROLLING標識當前設備為 “控制角色(Controlling)”,攜帶 Tie-breaker 解決角色沖突
ICE-CONTROLLED標識當前設備為 “被控角色(Controlled)”,攜帶 Tie-breaker 解決角色沖突
XOR-MAPPED-ADDRESS對映射地址進行 XOR 加密,防止 NAT 網關篡改地址(修復 ALG 設備的兼容性)
MESSAGE-INTEGRITY基于 HMAC-SHA1 的消息完整性校驗(用 ICE 協商的 ice-pwd 計算)
FINGERPRINTCRC32 指紋校驗,進一步區分 STUN 消息與其他協議(如 RTP/RTCP)

TURN:P2P 失敗時的中繼方案

當 STUN 無法打通 NAT(如兩端均為對稱型 NAT)時,ICE 會降級為 TURN(Traversal Using Relays around NAT) 中繼傳輸。TURN 本質是一個 “中繼服務器”,核心作用是:

  1. 為設備分配 Relay Candidate(中繼地址);
  2. 轉發兩端的音視頻數據(所有流量經 TURN 服務器中轉)。
TURN 的關鍵特性:
  • 協議兼容性:基于 STUN 擴展(除 ChannelData 消息外,其他消息格式與 STUN 一致),支持 UDP/TCP/TLS;
  • 權限控制:設備需先向 TURN 服務器發送 Allocate 請求 “申請中繼資源”,并創建 Permission(許可)—— 僅允許被許可的對端地址通過 TURN 轉發數據;
  • 效率優化:支持 ChannelData 消息(無 STUN 頭部,減少開銷),適合大流量傳輸。

1.5 ICE 細節

NAT 類型

NAT 網關的轉發規則直接決定 P2P 能否成功,ICE 需先檢測 NAT 類型,再選擇合適的 Candidate。常見 NAT 類型分為 圓錐型 NAT對稱型 NAT,其中圓錐型又細分為三類:

NAT 類型核心規則P2P 兼容性
完全圓錐型 NAT內網 IP:Port 映射為固定公網 IP:Port,任何外網設備可向該公網地址發送數據最佳(支持所有 P2P 場景)
IP 限制圓錐型 NAT內網 IP:Port 僅向 “主動訪問過的外網 IP” 開放(端口不限)較好(僅限制 IP,支持大部分場景)
Port 限制圓錐型 NAT內網 IP:Port 僅向 “主動訪問過的外網 IP:Port” 開放(IP + 端口雙重限制)一般(需精準匹配端口)
對稱型 NAT內網 IP:Port 向不同外網 IP:Port 發起請求時,映射不同的公網 IP:Port最差(P2P 幾乎無法打通,需 TURN 中繼)
NAT 類型檢測流程:

ICE 代理通過向 STUN 服務器發送多輪請求,按以下順序判斷 NAT 類型:

  1. 檢查防火墻是否阻斷所有 UDP 包(若無法收到 STUN 響應,判定為 “UDP 阻斷”);
  2. 檢查設備是否擁有公網 IP(若本地 IP 與 STUN 返回的映射地址一致,判定為 “公網設備”);
  3. 檢測是否為 “完全圓錐型 NAT”(向不同 STUN 服務器發送請求,若映射地址不變,且外部可主動訪問);
  4. 檢測是否為 “對稱型 NAT”(向同一 STUN 服務器的不同端口發送請求,若映射地址變化,判定為對稱型);
  5. 區分 “IP 限制” 與 “Port 限制圓錐型”(向同一 IP 的不同端口發送請求,若能收到響應則為 IP 限制,否則為 Port 限制)。

在這里插入圖片描述

具體能否打通可以看下表:

在這里插入圖片描述

ICE協議包括stun和turn協議,turn協議是stun協議的補充,可以簡單粗暴理解為如果stun不通,那就走turn,turn可以理解為一個中繼代理轉發。

在這里插入圖片描述

ICE 的角色與模式

ICE 定義了 “角色” 和 “模式”,用于規范兩端的行為邏輯,避免沖突。

(1)ICE 角色:Controlling vs Controlled

ICE 兩端分為兩種角色,決定 “誰負責提名可用路徑”:

  • Controlling(控制角色):主動提名 “可用的 Candidate Pair”,由 Offer 方(主動發起會話的設備)擔任;
  • Controlled(被控角色):被動接受 Controlling 提名的路徑,由 Answer 方(被動響應會話的設備)擔任。
角色沖突解決:

若兩端均誤判為 Controlling(或 Controlled),通過 Tie-breaker(隨機值) 解決:

  1. 沖突時,兩端在 STUN Binding 請求中攜帶 ICE-CONTROLLING/ICE-CONTROLLED 屬性及 Tie-breaker 值;
  2. 比較 Tie-breaker 大小:值更大的一端為 Controlling,另一端需切換為 Controlled;
  3. 若某端需切換角色,對端會返回 487(Role Conflict) 錯誤,觸發角色變更。
ICE 模式:Full ICE vs Lite ICE

ICE 代理分為兩種模式,對應不同的部署場景:

模式核心行為適用場景
Full ICE主動收集所有 Candidate,主動發起連通性檢查,支持角色切換客戶端設備(如瀏覽器、APP)
Lite ICE僅被動響應連通性檢查(不主動發起),角色固定為 Controlled,SDP 含 a=ice-lite公網服務器(如媒體服務器、CDN 節點)

注意:Full ICE 與 Lite ICE 互通時,僅 Full ICE 端主動發起檢查,Lite 端僅需回應即可。

ICE 的完整工作流程

ICE 從 “收集 Candidate” 到 “建立通信” 分為 8 個核心步驟,流程如下:

步驟 1:收集 Candidate(Candidate Collection)

ICE 代理從本地、STUN、TURN 收集所有可能的 Candidate,并去重(若兩個 Candidate 的地址和 Base 地址相同,則刪除重復項):

  • Host Candidate:遍歷本地網卡(物理 / 虛擬),獲取所有內網 / 公網 IP:Port;
  • Srflx Candidate:向 STUN 服務器發送 Binding Request,獲取 NAT 公網映射地址;
  • Relay Candidate:向 TURN 服務器發送 Allocate 請求,獲取中繼地址;
  • Foundation 生成:為每個 Candidate 生成唯一標識(基于類型、IP、協議計算),用于后續去重。
步驟 2:交換 Candidate(Candidate Exchange)

兩端通過 信令服務器 交換 Candidate(需與 SDP 協商同步),有兩種交換方式:

  1. 傳統方式:收集完所有 Candidate 后,將其嵌入 SDP 中一次性發送;
  2. Trickle ICE(涓流 ICE):SDP 與 Candidate 分開發送(SDP 先發送,Candidate 收集一個發一個),SDP 需包含 a=ice-options:trickle

優勢:Trickle ICE 可縮短連接建立時間(無需等待所有 Candidate 收集完成),是 WebRTC 的默認方式。

SDP 中 Candidate 的格式示例:
a=candidate:240568271 1 udp 1686052607 174.139.8.82 64462 typ srflx raddr 10.1.1.19 rport 64462 generation 0 ufrag TWCy network-id 2

字段含義解析:

字段含義
240568271Foundation(Candidate 唯一標識)
1Component ID(媒體類型:1=RTP,2=RTCP;WebRTC 默認用 RTCP-mux 合并為 1)
udp傳輸協議(UDP/TCP)
1686052607Priority(Candidate 優先級,數值越大優先級越高)
174.139.8.82Candidate 地址(公網映射地址,對應 Srflx 類型)
64462端口號
typ srflxCandidate 類型(host/srflx/prflx/relay)
raddr 10.1.1.19Base 地址(Srflx 的本地內網地址)
ufrag TWCyICE 用戶名片段(用于 STUN 認證,與對端 ufrag 組合為 USERNAME)
步驟 3:生成 Candidate Pair(候選地址對)

兩端收到對方的 Candidate 后,按以下規則組合為 Candidate Pair(本端 Candidate + 遠端 Candidate)

  • 匹配條件:Component ID 相同(如均為 RTP 的 1)且 傳輸協議相同(如均為 UDP);
  • 地址修整:若 Candidate 為 Srflx,需用其 Base 地址(本地內網地址)替換,確保檢查邏輯正確。
步驟 4:連通性檢查(Connectivity Checks)

ICE 按 Candidate Pair 的優先級 排序(優先級高的先檢查),通過 STUN Binding Request/Response 驗證 “該地址對是否能互通”。

(1)Candidate Pair 優先級計算

優先級決定檢查順序,公式如下(核心邏輯:優先選擇 “本地優先” 且 “對端優先” 的組合):

Pair Priority = 2^32 * MIN(G, D) + 2 * MAX(G, D) + (G > D ? 1 : 0)
  • G:Controlling 角色的 Candidate 優先級;
  • D:Controlled 角色的 Candidate 優先級;
  • MIN(G,D)/MAX(G,D):取兩者的最小值和最大值,確保 “高優先級 Candidate 優先匹配”。
(2)檢查方式
  • Ordinary Checks(普通檢查):Controlling 端按優先級順序,主動向 Controlled 端發送 STUN Binding Request;
  • Triggered Checks(觸發式檢查):Controlled 端收到檢查請求后,立即向 Controlling 端發起反向檢查(提高效率,避免等待)。
(3)檢查成功的條件
  1. 收到對端的 STUN Binding Success Response
  2. 地址對稱:請求的 “源地址 = 響應的目的地址” 且 “請求的目的地址 = 響應的源地址”(排除 NAT 地址映射不對稱的情況)。
(4)重傳機制

若未收到響應,ICE 按 指數退避策略 重傳(初始間隔 50ms,每次翻倍,直至最大重傳次數或超時)。

步驟 5:生成 Valid List(有效地址列表)

將 “連通性檢查成功” 的 Candidate Pair 按優先級排序,組成 Valid List(可用路徑列表)。

步驟 6:提名 Candidate Pair(Nomination)

Controlling 角色 從 Valid List 中選擇 “最優路徑” 并提名,分為兩種提名方式:

  • 普通提名(Regular Nomination):分兩步檢查
    1. 第一次檢查:不帶 USE-CANDIDATE 屬性,僅驗證連通性;
    2. 第二次檢查:對 Valid List 中的 Pair 發送帶 USE-CANDIDATE 的請求,確認提名。
  • 進取型提名(Aggressive Nomination):一步完成
    1. 所有檢查請求均帶 USE-CANDIDATE 屬性;
    2. 第一個檢查成功的 Pair 直接被提名(效率更高,WebRTC 默認采用)。
步驟 7:建立加密連接(DTLS)

提名完成后,兩端基于 “選中的 Candidate Pair” 建立 DTLS(數據報傳輸層安全)連接——WebRTC 要求所有數據(音視頻、DataChannel)必須加密,DTLS 負責證書交換、密鑰協商,確保傳輸安全。

步驟 8:連接保活(Keep-Alive)

NAT 網關會 “超時清理” 長期無數據的連接(默認超時時間 30s~5min),ICE 通過以下方式保活:

  • 定期發送 STUN Binding Request/Indication(初始間隔 50ms,穩定后間隔 2.5s);
  • 若未收到響應,觸發重傳或重新選擇 Valid List 中的備用路徑。

ICE 的狀態流轉

ICE 代理在工作過程中會經歷以下狀態,用于標識連接進展:

狀態含義
Waiting未開始連通性檢查,等待 Candidate 收集或交換完成
In-Progress連通性檢查已啟動,但尚未有成功的 Pair
Succeeded已找到可用的 Candidate Pair,DTLS 連接建立完成,可開始數據傳輸
Failed所有 Candidate Pair 檢查失敗,且 TURN 中繼不可用(連接徹底失敗)
FrozenCandidate Pair 暫不檢查(如等待其他 Pair 檢查結果,后續可解凍)

在這里插入圖片描述

二、WebRTC ICE的意義

2.1 價值

  • 解決 NAT 穿越難題:通過多 Candidate 類型和動態檢查,覆蓋 90% 以上的網絡場景;
  • 優先 P2P 通信:減少對中繼服務器的依賴,降低延遲(P2P 延遲通常 <100ms,中繼延遲可能> 200ms);
  • 可靠性保障:Valid List 提供備用路徑,某條路徑中斷時可快速切換到其他路徑。

2.2 局限性

  • 依賴信令服務器:ICE 需信令服務器交換 SDP 和 Candidate,無法獨立工作;
  • 對稱型 NAT 需中繼:對稱型 NAT 下 P2P 無法打通,需依賴 TURN 服務器(增加帶寬成本和延遲);
  • 防火墻限制:部分嚴格防火墻會阻斷 UDP 端口,需降級為 TCP/TLS(效率較低)。

2.3 總結

ICE 是 WebRTC 實現 “實時 P2P 通信” 的核心支柱,它通過 “收集候選地址→檢查連通性→提名最優路徑” 的閉環流程,繞開了 NAT 網關的限制,同時整合 STUN 和 TURN 實現 “P2P 優先、中繼兜底” 的通信策略。理解 ICE 的工作原理,是排查 WebRTC 連接失敗(如 “無法建立 P2P 連接”“延遲過高”)的關鍵 —— 例如,連接失敗可能是 STUN/TURN 服務器不可用、NAT 類型為對稱型且無中繼資源,或 Candidate 交換不完整。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/97843.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/97843.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/97843.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux0.12 head.s代碼解析

重新設置IDT和GDT&#xff0c;為256個中斷門設置默認的中斷處理函數檢查A20地址線是否啟用設置數學協處理器將main函數相關的參數壓棧設置分頁機制&#xff0c;將頁表映射到0~16MB的物理內存上返回main函數執行 源碼詳細注釋如下: /** linux/boot/head.s** (C) 1991 Linus T…

Maven動態控制版本號秘籍:高效發包部署,版本管理不再頭疼!

作者&#xff1a;唐叔在學習 專欄&#xff1a;唐叔的Java實踐 關鍵詞&#xff1a;Maven版本控制、versions插件、動態版本號、持續集成、自動化部署、Java項目管理 摘要&#xff1a;本文介紹如何使用Maven Versions插件動態控制項目版本號和依賴組件版本號&#xff0c;實現無需…

簡述:普瑞時空數據建庫軟件(國土變更建庫)之一(變更預檢查部分規則)

簡述&#xff1a;普瑞時空數據建庫軟件&#xff08;國土變更建庫&#xff09;之一(變更預檢查部分規則) 主要包括三種類型&#xff1a;常規檢查、行政區范圍檢查、20X異常滅失檢查 本blog地址&#xff1a;https://blog.csdn.net/hsg77

shell中命令小工具:cut、sort、uniq,tr的使用方式

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄前言一、cut —— 按列或字符截取1. 常用選項2. 示例二、sort —— 排序&#xff08;默認按行首字符升序&#xff09;1. 常用選項常用 sort 命令選項三、uniq —— 去…

【Linux】Linux開發必備:Git版本控制與GDB調試全指南

前言&#xff1a;在Linux開發流程中&#xff0c;版本控制與程序調試是保障項目穩定性和開發效率的兩大核心環節。Git作為當前最主流的分布式版本控制系統&#xff0c;能高效管理代碼迭代、追蹤修改記錄并支持多人協同開發&#xff1b;GDB&#xff08;GNU調試器&#xff09;是Li…

實現 TypeScript 內置工具類型(源碼解析與實現)

目標讀者&#xff1a;已經熟悉 TypeScript 基礎語法、泛型、條件類型的同學。本文按常見工具類型的分類與順序實現并解釋 Partial、Required、Readonly、Pick、Omit、Record、Exclude、Extract、NonNullable、ReturnType、Parameters、ConstructorParameters、InstanceType、Th…

Spring Boot + Nacos 配置中心示例工程

1?? 工程結構 nacos-demo├── pom.xml└── src├── main│ ├── java│ │ └── com.example.nacosdemo│ │ ├── NacosDemoApplication.java│ │ ├── config│ │ │ └── AppProperties.java│ │ └── cont…

(二)文件管理-基礎命令-pwd命令的使用

文章目錄1. 命令格式2. 基本用法3. 高級用法4. 注意事項1. 命令格式 pwd [OPTION]...[OPTION]: 可選選項&#xff0c;用于改變命令的默認行為。最主要的兩個選項是 -L 和 -P。它不需要任何參數&#xff08;如文件名或目錄名&#xff09; 2. 基本用法 用法&#xff1a;pwd 是…

Leetcode_202.快樂數_三種方法解決(普通方法解決,哈希表解決,循環鏈表的性質解決_快慢指針)

目錄第一種方法&#xff1a;暴力解法暴力ac代碼&#xff1a;第二種方法&#xff1a;哈希表哈希表ac代碼:第三種方法&#xff1a;根據循環鏈表的性質(快慢指針)第一種方法&#xff1a;暴力解法 最暴力的思路就是直接使用循環往下一直計算&#xff0c;這樣特別浪費時間&#xff…

代碼隨想錄刷題Day48

這次博客主要是對做過的關于二叉樹系列的題目進行整理和分類。二叉樹&#xff0c;要處理整個樹&#xff0c;一般少不了遍歷。遍歷主要可以分為&#xff1a;遞歸系列、層序遍歷。如果不遍歷的話&#xff0c;那就是處理特殊的樹了&#xff0c;比如完全二叉樹。遞歸系列基本的遞歸…

汽車工裝結構件3D掃描尺寸測量公差比對-中科米堆CASAIM

汽車制造過程中&#xff0c;工裝結構件的尺寸精度對整車裝配質量和生產進度有重要影響。傳統測量工具如卡尺和三坐標測量機采用接觸式工作方式&#xff0c;檢測過程耗時較長&#xff0c;對于具有復雜曲面特征的工件&#xff0c;難以全面獲取尺寸數據。激光三維掃描技術改變了傳…

Docker Pull 代理配置方法

本文介紹通過網絡代理加速Docker鏡像拉取的方法。 配置方法 當執行docker pull從Docker Hub 拉取鏡像時&#xff0c;其網絡連接由守護進程docker daemon進行維護。 要修改其代理設置&#xff0c;可配置其systemd服務&#xff0c;步驟如下&#xff1a; &#xff08;1&#xf…

機電裝置:從基礎原理到前沿應用的全方位解析

本文由「大千AI助手」原創發布&#xff0c;專注用真話講AI&#xff0c;回歸技術本質。拒絕神話或妖魔化。搜索「大千AI助手」關注我&#xff0c;一起撕掉過度包裝&#xff0c;學習真實的AI技術&#xff01; 1 機電裝置的基本概念與發展歷程 機電裝置&#xff08;Mechatronic D…

《SVA斷言系統學習之路》【03】關于布爾表達式

序列中使用的表達式基于其所含變量的采樣值進行評估。表達式評估的結果為布爾值&#xff0c;其解釋方式與過程性if語句條件中的表達式完全相同&#xff1a;若表達式計算結果為X、Z 或 0&#xff0c;則被解釋為假&#xff1b;否則即為真。但是&#xff0c;對可出現在并發斷言中的…

指針高級(2)

6.數組指針#include <stdio.h> int main() {/*練習&#xff1a;利用指針遍歷數組*///1.定義數組int arr[] { 10,20,30,40,50 };int len sizeof(arr) / sizeof(int);//2.獲取數組的指針//實際上獲取的&#xff1a;數組的首地址int* p1 arr;int* p2 &arr[0];printf…

如何高效記單詞之:抓住首字母——以find、fund、fond、font為例

find、fund、fond、font這幾個單詞&#xff0c;你都認識嗎&#xff1f;這幾個單詞&#xff0c;意思大體如下&#xff1a; find v.找到&#xff1b;發現fund n.基金fond a.喜歡的&#xff1b;喜愛的&#xff1b;深情的font n.字體&#xff0c;字型&#xff0c;字形 這幾個單詞在…

Ubuntu下把 SD 卡格式化為 FAT32

在 Ubuntu 下把 SD 卡格式化為 FAT32&#xff0c;按下面做&#xff08;會抹掉整卡數據??&#xff09;&#xff1a; 1) 找到你的 SD 卡設備名 lsblk -p記下整盤設備&#xff0c;比如 /dev/sdb&#xff08;USB 讀卡器常見&#xff09;或 /dev/mmcblk0&#xff08;內置讀卡器&am…

涉私數據安全與可控匿名化利用機制研究(上)

文章目錄前言一、涉私數據的概述及分類&#xff08;一&#xff09;涉私數據的“知情同意原則”&#xff08;二&#xff09;涉私數據的分類二、涉私數據可控匿名化利用機制&#xff08;一&#xff09;數據產品與涉私數據的利用形式&#xff08;二&#xff09;通過可信數據空間受…

Redis 的跳躍表:像商場多層導航系統一樣的有序結構

目錄 一 、從 "超市貨架" 的痛點看跳躍表的價值 1.1、跳躍表與商場導航系統的結構對應 1. 1.1、zskiplistNode&#xff1a;帶導航標記的 "商品"&#xff08;跳躍表節點&#xff09; 1.1.1.1、level []&#xff1a;商品上的多層導航標記 1.1.1.2、back…

小程序點擊之數據綁定

<return /><view class"all-wrap" style"padding-top:{{topHeight}}px;"><view class"my-title">我的收藏</view><scroll-viewclass"collect-list-container"scroll-yscroll-top"{{scrollTop}}"…