小编用过很多的聊天软件,自己心血来潮也想做一个相关的聊天软件,但是碍于不会音频视频通话这项技术,只能开启自学之旅,今天是学习的第一天,后续会不断打卡(当然,小编没写过几篇文章,排版不美观请见谅)。

        俗话说:一口吃不下一个胖子,学习技术也是这样,这点小编深有体会(之前java基础都不会就直接跑去看框架,结果就是被完虐)所以前面的学习,并不涉及代码,只是一些扎实地基的理论知识,毕竟万丈高楼平地起嘛😊😊

了解核心概念:

        一、什么是信令?

        二、什么是SDP?

        三、NAT穿透与ICE框架

一、了解信令

        一、基本概念:

        在 WebRTC(或所有实时音视频实时通信系统)中,信令(Signaling)是一套 “辅助通信机制”,它不直接传输音视频数据,而是负责在通信双方(如两个浏览器、两台设备)之间传递 “连接所需的控制信息”,确保双方能顺利建立、维护和终止实时媒体连接。

        上述说的那么专业,那实际上是什么意思呢?信令这个东西我们可以看成是老一辈人生活里的一个 ”媒婆“,它作为一个中间的媒介,并不会一上来就让男女双方就结婚(对应传输视频数据),但是没有它,男女双方又无法见面,它负责一下的事情:

  1. 传递 “交友意愿”:你告诉婚介所 “想找个能视频聊天的对象”,婚介所把这话转给合适的人,问对方 “愿不愿接这个视频邀约”—— 这就像信令在传 “要不要建立连接” 的控制信息
  2. 交换 “关键条件”:对方同意后,婚介所会帮你俩互通 “细节”:比如你说 “我这边视频只能用 XX 软件、网络信号在客厅最好”,对方说 “我用 XX 格式接收更清晰”—— 这就像信令传递 “设备能力、网络参数”,确保双方 “对接规则一致”;
  3. 敲定 “见面方式”:婚介所最后跟你俩确认 “今晚 8 点,用 XX 软件的 XX 房间号连”,等你俩都点头,才算完成 “牵线”—— 这就像信令敲定连接细节,为后续传音视频数据铺路。

所以你们看,这个 “信令” 全程就是一个打辅助的,男女双方(即通信的双方)并没有直接进行对话,而都是靠这个 “信令” 来传递消息,让双方达成连接共识 

二、信令的核心作用:

        在了解完 “信令” 是个什么东西之后,接下来我们就该了解一下信令的核心作用是什么了,核心作用就是这以下三点了:

        1、 “你是谁,你在哪”—— 交换网络位置信息

                在 “媒婆” 介绍的时候,总要了解一下你是哪里人,住哪里,之后牵线成功了才能让你的对象找到你,这就好比计算机中的 IP 地址了,但平常的话我们都在家中,设备通常处于路由器(NAT)之后(如家用 WiFi 的 192.168.x.x 是内网地址,不直接暴露在公网),无法直接获取对方的公网可达地址。信令的作用之一就是传“ICE 候选地址”递(由 STUN/TURN 服务器生成,包含设备的公网 / 内网地址和端口),让双方知道 “可以通过哪些地址找到对方”。

        2、“我们能聊什么,用什么格式聊”—— 协商媒体能力

                那初步的了解对方之后,觉得对方符合自己的基本要求,我们肯定就想更加了解对方了,这个时候就要想想双方之间能聊什么,怎么聊?微信 OR QQ ?这就类似于计算机中不同设备支持的音视频编码格式、分辨率、采样率可能不同(比如 A 设备只支持 H.264 视频编码,B 设备只支持 VP9)。
信令需要传递 “SDP(会话描述协议)” 信息:A 会把自己支持的媒体格式、带宽限制等打包成 SDP 发给 B,B 根据自己的能力回复一个 “兼容的 SDP”,最终双方确定一套共同支持的规则(如 “用 OPUS 编码传音频,H.264 编码传视频”)

        比如:A支持微信、QQ聊天,但是 B 只支持微信聊天,这样双方一交换,最终敲定我们都用微信聊天

        3、 “怎么开始聊,怎么结束聊”—— 控制连接生命周期

                1、发起通话:你想视频,先给她发微信:“来个视频呗?”—— 这就是信令在传 “邀请”,朋友得先收到这条 “消息”,才知道你要连他

                2、接听通话:朋友看到消息回你:“好,我点接听了!”—— 这是信令通知你 “对方同意了”,你俩的设备才会开始准备传画面声音

                3、挂断通话:你有事要结束,先发消息:“我先挂啦”,或者直接点挂断后,系统悄悄发个 “我要断了” 的消息给朋友 —— 这是信令传 “终止信号”,让朋友的设备知道 “不用再接收数据了”,避免他那边还卡着 “等待画面”;

                4、中途关摄像头:你想暂时关摄像头,会先通过 “消息” 告诉朋友:“我关下摄像头,不是断了啊”—— 这是信令传 “调整指令”,朋友那边才会显示 “对方已关闭摄像头”,而不是以为自己卡了

        以上就是 “信令” 得做的事情,没有它,双方都不知道对方在干嘛,那就没得聊咯~

二、了解SDP

        一、基本概念:

              在 WebRTC 中,SDP(全称:Session Description Protocol) 是媒体协商的核心载体,解决两个关键问题:

                1、能力声明:让双方知道对方支持的媒体类型(音频 / 视频)、编码格式(如 H.264、VP8 视频编码,OPUS 音频编码)、采样率、分辨率等。

                2、资源约定:确定媒体流传输的网络地址、端口、传输协议(如 RTP 实时传输协议)等,确保数据能正确发送到对方的接收端点。

        这个步骤其实就是上述“信令”中的协商媒体能力

        二、SDP的结构:由多行键值对组成

                SDP 格式采用 纯 文 本,每行以一个字母(称为 “类型字段”)开头, followed by 等号和具体值,结构清晰但信息密集。以下是一个简化的 WebRTC SDP 示例及关键字段解析:

v=0                  // 版本号(固定为0)
o=- 123456789 1 IN IP4 192.168.1.100  // 会话发起者信息(ID、IP等)
s=-                  // 会话名称(WebRTC中通常为空)
c=IN IP4 0.0.0.0     // 连接信息(IP地址,WebRTC中暂用0.0.0.0,后续由ICE补充)
t=0 0                // 会话时间(0 0表示持久有效)
m=audio 9 UDP/TLS/RTP/SAVPF 111      // 音频媒体行:端口9,协议,支持的编码ID(111对应OPUS)
a=rtpmap:111 opus/48000/2            // 音频编码详情:ID111是OPUS编码,采样率48000Hz,双声道
a=fmtp:111 minptime=10;useinbandfec=1 // OPUS编码参数(最小包时间10ms,启用带内FEC抗丢包)
a=rtcp-mux                            // 音频和RTCP(控制协议)复用同一端口
m=video 9 UDP/TLS/RTP/SAVPF 96        // 视频媒体行:端口9,协议,支持的编码ID(96对应H.264)
a=rtpmap:96 H264/90000                // 视频编码详情:ID96是H.264,时钟频率90000Hz
a=fmtp:96 level-asymmetry-allowed=1   // H.264编码参数
a=rtcp-mux                            // 视频和RTCP复用同一端口
a=ice-ufrag:abcd                      // ICE用户名片段(用于NAT穿透验证)
a=ice-pwd:1234567890abcdef            // ICE密码(用于NAT穿透验证)
a=fingerprint:sha-256 ABCD...         // 加密指纹(用于验证SDP完整性,防止篡改)

        二、SDP 在 WebRTC 中的工作流程

                在 WebRTC 的 “媒体协商” 阶段,SDP 会经历 “offer-answer”(提议 - 应答)交换过程,过程如下:

                发起方(A)生成 offer SDP
                A 通过RTCPeerConnection.createOffer()生成包含自己媒体能力的 SDP(如支持的音视频编码、设备信息),并通过信令发送给接收方(B)。

                接收方(B)生成 answer SDP
                B 收到 offer 后,通过RTCPeerConnection.setRemoteDescription()解析 A 的 SDP,然  后用createAnswer()生成 “应答 SDP”—— 这份 SDP 会从 A 支持的编码中筛选出 B 也支持的格式(如 A 支持 H.264 和 VP8,B 只支持 H.264,则 answer 中只保留 H.264),再通过信令回传给A

                双方确认协商结果
                A 收到 answer 后,通过setRemoteDescription()解析 B 的 SDP,此时双方已明确共同支持的媒体规则(编码、传输协议等),后续音视频流将按此规则传输。

        三、SDP 的特点与注意事

                纯描述性:SDP 只 “描述” 如何通信,不负责 “执行” 通信(实际传输由 RTP 协议完成)

                动态生成:在 WebRTC 中,SDP 由RTCPeerConnection自动生成,开发者无需手动编写,但需要理解其协商逻辑(如为什么某些编码不被支持)。

                与 ICE 配合:SDP 中的c=IN IP4 0.0.0.0是占位符,实际的网络地址(公网 / 内网 IP 和端口)由 ICE 框架生成的 “ICE Candidate” 补充,两者共同完成连接建立。

三、NAT穿透与ICE框架

        一、什么是NAT

                NAT(全称:Network Address Translation,网络地址转换) 是一种网络技术,通过将局域网(LAN)内的私有 IP 地址转换为互联网(WAN)可识别的公有 IP 地址,解决了 “公有 IP 地址数量不足” 的问题,同时隐藏了内网设备,提升了网络安全性。

        二、NAT的核心作用

                1、节省公有 IP:内网所有设备共享 1 个(或少量)公有 IP 接入互联网,无需为每台设备分配独立公有 IP。

                2、隔离内网与外网:外网无法直接访问内网私有 IP,仅能通过 NAT 设备(如路由器)转发的请求交互,减少内网被攻击的风险。

                3、解决 IP 地址冲突:私有 IP 仅在局域网内有效,不同内网可使用相同的私有 IP 段(如 192.168.1.x),无需担心与其他网络冲突。

        三、NAT 的工作原理(以 “内网设备访问外网” 为例)

                私有 IP:仅用于局域网内部通信的 IP,无法直接访问互联网,常见网段:

                        192.168.0.0 ~ 192.168.255.255 (最为常用的)

                        10.0.0.0 ~ 10.255.255.255

                        172.16.0.0 ~ 172.31.255.255

                公有 IP:由运营商分配、互联网唯一可识别的 IP,如 202.103.XX.XX

                NAT 转换表:NAT 设备(如路由器)内记录的 “私有 IP + 端口” 与 “公有 IP + 端口” 的映射关系,用于后续数据回传。              .

  

上述是一张内网手机 / 电脑(私有 IP 192.168.1.100)发起访问百度的请求流程图

        四、常见的NAT类型以及说明

类型 特点 使用场景
静态 NAT(Static NAT) 私有 IP 与公有 IP 一对一固定映射 内网服务器(如网站、监控)需外网固定访问
动态 NAT(Dynamic NAT) 私有 IP 从公有 IP 池(多个公有 IP)中动态获取映射 内网设备较多,需多个公有 IP 轮用
端口地址转换(PAT) 多个私有 IP 共享 1 个公有 IP,通过 “不同端口” 区分 家庭、小型企业(最常用,如路由器默认模式)

        上述表格中有动态的NAT和静态的NAT,那么这两个有什么区别呢?我们来看看:

                动态NAT(Dynamic NAT)

                        动态NAT通过地址池将内部私有IP动态映射到公有IP。每次内部设备发起连接时,NAT设备从地址池中随机分配一个可用公有IP,映射关系在会话结束后释放

                特点

                        1、公有IP与私有IP的映射关系不固定,随会话动态变化

                        2、适合内部设备数量较多但并发连接数少于地址池容量的场景

                        3、无法从外部直接访问内部主机,缺乏确定性映射

                静态NAT (Static NAT)

                        静态NAT为内部私有IP和公有IP建立一对一的固定映射关系,映射配置后长期有效

                特点:

                        1、公有IP与私有IP的绑定是永久性的,不受会话影响

                        2、支持从外部通过公有IP直接访问内部主机(如服务器)

                        3、适用于需要提供稳定对外服务的场景(如Web服务器)

                下面我们画两幅简单的图来看一下静态NAT和动态NAT有什么区别:

动态NAT:                                        

静态NAT:

从上述的两张图就能很明显的看出来,如果使用的是静态NAT的话,当 “电脑1” 不再传递数据了,但他依然会霸占着一个共有的地址,其他电脑就用不了了,算是 “占着茅坑不拉屎”,这样肯定不行,如果使用的是动态NAT的话,当 “电脑1” 不用了,就把地址释放出来,造福于别的计算机,给别人使用,下次再使用的时候再找一个没使用过的地址,这样就好理解为什么动态NAT的映射关系不固定了

        端口地址转换(PAT 全称:Port Address Translation)

                称为网络地址端口转换(NAPT),是 NAT 技术中最常用的一种实现方式。它通过 “IP 地址 + 端口号” 的组合 来区分不同的内网设备,实现多个内网设备共享一个或少量公有 IP 地址访问互联网的功能,是家庭、企业网络中路由器的默认工作模式

                普通的静态 / 动态 NAT 是 “IP 地址一对一映射”(一个内网设备占用一个公有 IP),而 PAT 通过端口区分实现了 “多对一” 映射:

                即 多个内网设备→共享 1 个公有 IP→通过不同端口号区分各自的网络会话

                PAT工作原理:

                        会话(Session):每个网络请求(如浏览网页、发消息)都是一个独立会话,用 “源 IP + 源端口 + 目标 IP + 目标端口 + 协议” 唯一标识。

                        PAT 转换表:记录 “内网设备(私有 IP + 端口)” 与 “公有 IP + 端口” 的映射关系,用于数据回传时的反向查找。

                PAT核心特点:

                        多设备共享公有 IP:理论上,一个公有 IP 通过 65535 个端口(0~65535),可同时支持数万设备上网(实际受路由器性能限制)

                        端口是区分关键:不同内网设备的会话通过 “公有 IP + 不同端口” 区分,避免混淆

                        隐藏内网细节:外网只能看到公有 IP 和端口,无法直接获取内网设备的私有 IP,提升安全性

                        会话结束释放端口:当设备的网络会话结束(如关闭网页),路由器会删除转换表中的对应记录,释放端口供其他会话使用

                下边画了一幅流程图,大家可以看一下,有助于各位理解,如下图: 

                PAT的局限性以及解决的方法:

                        局限性:外网无法主动访问内网设备(因 PAT 转换表仅在 “内网主动发起请求” 时生成,且端口随机)

                        解决方法:

                                静态 PAT(端口映射):手动配置 “公有 IP: 端口→内网 IP: 端口” 的固定映射(如将路由器的 80 端口映射到内网 Web 服务器的 80 端口,让外网可访问)

                                NAT 穿越技术:通过 UPnP、STUN 等协议,让内网设备主动向外网暴露映射信息(如 P2P通信、视频会议)

                

        五、什么是NAT穿透

                概念:

                        NAT 穿透(NAT Traversal,简称 NAT-T) 是一种技术,用于解决处于不同 NAT 设备后的内网设备,无法直接建立点对点(P2P)通信的问题,让它们能绕过 NAT 的地址转换限制,实现直接数据交互

                为什么需要NAT穿透?

                        NAT 的核心作用是 “内网私有 IP→外网公有 IP” 的转换,让多个内网设备共享一个公有 IP 上网。但这一机制会导致 “单向通信” 限制 :

                        第一:只有内网设备主动向外网发起请求(如访问网页),NAT 才会临时开放端口、允许外网响应

                        第二:若外网设备(或另一内网设备)主动向内网设备发起连接(如 P2P 文件传输、视频通话),NAT 会直接拦截请求,因为它没有 “预存的端口映射规则”,不知道该转发给哪个内网设备

                常见的NAT穿透技术:

                        一、STUN(会话穿越实用工具)

                       使用场景:使用于大多数的P2P场景(视频通话),需配合STUN服务器

                       原理:

                           1、内网设备 A、B 分别向公网的 STUN 服务器发起请求

                           2、STUN 服务器会 “告诉” 设备 A/B:“你的 NAT 分配的外网 IP 是XX.XX.XX.XX,临时开放的端口是 XXXX”(即设备的 “公网映射地址”)

                           3、设备 A、B 通过第三方渠道(如聊天服务器)交换彼此的 “公网映射地址”

                           4、双方同时向对方的 “公网映射地址” 发起连接请求,NAT 会识别到 “这是内网设备主动发起的反向请求”,从而允许连接建立

                        二、TURN(中继穿透)

                        使用场景:STUN 无法穿透的复杂 NAT(如对称 NAT),需配合 TURN 服务器

                        原理:当 STUN 无法让两个内网设备直接连接时,双方会将数据 “转发到公网的 TURN 服务器”,由 TURN 服务器作为 “中间桥梁”,将 A 的数据转发给 B

                        三、ICE框架(交互式连接建立)

                        说明:它不是一项单独的技术,而是一套组合拳,是由 “STUN + TURN” 组合而成的解决方案

                        原理:设备优先尝试用 STUN 获取公网地址、直接建立 P2P 连接(延迟低);若 STUN 失败,则自动切换到 TURN 服务器进行中继(确保连接成功),兼顾 “效率” 和 “稳定性”

                通俗的说明NAT穿透:

                 你住在一个小区(内网),小区只有一个大门和一个对外的门牌号(路由器的公有 IP),你家在小区里有个专属房间号(你的设备私有 IP)。

                平时你网购(内网设备主动访问外网),会跟快递员说 “送 XX 小区,到了打电话我去门口取”—— 这时候小区保安(NAT)知道 “是 3 号楼 201 的住户要收快递”,会放行快递车到门口

                但如果反过来:你朋友想给你寄个东西(外网 / 另一个内网的设备,想主动连你),只知道小区门牌号(公有 IP),不知道你家房间号(私有 IP)。保安(NAT)根本没接到 “你要收朋友快递” 的提前通知,会直接拦住:“我不知道该送哪户,拒收!”—— 这就是 NAT 的 “拦截问题”。

                NAT 穿透,就是帮你解决 “朋友寄快递送不进家” 的办法:
        它相当于你提前跟保安打了招呼(或找了个 “中间人”),让保安知道 “朋友的快递是给 3 号楼 201 的”,或者帮你把快递转交到家里,最终让你和朋友能直接 “递东西”(设备间直接通信)

今天这一章的内容就到这里啦,后续还会实时更新的,后续应该会拿代码写一个 “信令” 了,感兴趣的话可以点赞关注一下!(●ˇ∀ˇ●)

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐