惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Schneier on Security
GbyAI
GbyAI
H
Help Net Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
The Blog of Author Tim Ferriss
Vercel News
Vercel News
Microsoft Azure Blog
Microsoft Azure Blog
Google DeepMind News
Google DeepMind News
Stack Overflow Blog
Stack Overflow Blog
AWS News Blog
AWS News Blog
Spread Privacy
Spread Privacy
Apple Machine Learning Research
Apple Machine Learning Research
L
LINUX DO - 最新话题
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
P
Privacy International News Feed
C
CERT Recently Published Vulnerability Notes
C
Cybersecurity and Infrastructure Security Agency CISA
I
Intezer
Hugging Face - Blog
Hugging Face - Blog
H
Heimdal Security Blog
N
News and Events Feed by Topic
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Troy Hunt's Blog
大猫的无限游戏
大猫的无限游戏
SecWiki News
SecWiki News
Martin Fowler
Martin Fowler
人人都是产品经理
人人都是产品经理
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Application and Cybersecurity Blog
Application and Cybersecurity Blog
F
Fortinet All Blogs
Hacker News: Ask HN
Hacker News: Ask HN
Know Your Adversary
Know Your Adversary
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 聂微东
S
Secure Thoughts
云风的 BLOG
云风的 BLOG
O
OpenAI News
The Cloudflare Blog
Jina AI
Jina AI
U
Unit 42
L
Lohrmann on Cybersecurity
Attack and Defense Labs
Attack and Defense Labs
The Register - Security
The Register - Security
G
Google Developers Blog
量子位
Simon Willison's Weblog
Simon Willison's Weblog
V
Visual Studio Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
G
GRAHAM CLULEY
TaoSecurity Blog
TaoSecurity Blog

Sekyoro的博客小屋

Agent从入门到开发 从自动化测试到游戏脚本:使用Maafw开发 Claude Code 实战 Beyond AI Coding:Harness工程与更好地AI开发 C++重点知识回顾 项目场景扩展(二) OpenClaw学习与实战 项目场景扩展(一) 搭建Agent+MCP+SKILL进行成熟Vibe Coding 分布式IM聊天系统学习 AI工具尝鲜:从"模态爆发"到"生态耕耘" Java、JVM、并发进阶 经典算法题解析 线段树问题 服务器网站备份实战 cls文件编写实战 智力题总结 RAG系统设计 从零开始大数据 资源调度与项目管理平台 凤凰架构学习 博客网站构建指南 k8s学习 Java进阶知识 操作系统与计算机网络经典 构建AI应用程序的框架以及解决方案 MySQL与Redis经典面经 刷题总结篇
网络中有趣的协议
本文作者: Sekyoro · 2026-05-27 · via Sekyoro的博客小屋

介绍一些网络协议,主要内容来自极客时间趣谈网络协议.

直播中用到的协议

直播主要是视频,本质可以看作图片流。假设30帧的视频,像素1024*768,每个像素由RGB组成,每个8位,共24位。一秒钟的数据量30帧 × 1024 × 768 × 24 = 566,231,040Bits = 70,778,880Bytes达到4个G.

因此需要通过压缩或者说编解码减少数据传输,既然压缩,就要规定编解码协议

频流中的图片进行压缩,因为视频和图片有这样一些特点。

  1. 空间冗余:图像的相邻像素之间有较强的相关性,一张图片相邻像素往往是渐变的,不是突变的,没必要每个像素都完整地保存,可以隔几个保存一个,中间的用算法计算出来。
  2. 时间冗余:视频序列的相邻图像之间内容相似。一个视频中连续出现的图片也不是突变的,可以根据已有的图片进行预测和推断。
  3. 视觉冗余:人的视觉系统对某些细节不敏感,因此不会每一个细节都注意到,可以允许丢失一些数据。
  4. 编码冗余:不同像素值出现的概率不同,概率高的用的字节少,概率低的用的字节多,类似霍夫曼编码(Huffman Coding)的思路。

视频编码流派

流媒体协议名称如下

  • 名词系列一:AVI、MPEG、RMVB、MP4、MOV、FLV、WebM、WMV、ASF、MKV。
  • 名词系列二:H.261、 H.262、H.263、H.264、H.265。
  • 名词系列三:MPEG-1、MPEG-2、MPEG-4、MPEG-7。

  • 流派一:ITU(International Telecommunications Union)的VCEG(Video Coding Experts Group),这个称为国际电联下的VCEG。既然是电信,可想而知,他们最初做视频编码,主要侧重传输。名词系列二,就是这个组织制定的标准。

  • 流派二:ISO(International Standards Organization)的MPEG(Moving Picture Experts Group),这个是ISO旗下的MPEG,本来是做视频存储的。例如,编码后保存在VCD和DVD中。当然后来也慢慢侧重视频传输了。名词系列三,就是这个组织制定的标准。

后来,ITU-T(国际电信联盟电信标准化部门,ITU Telecommunication Standardization Sector)与MPEG联合制定了H.264/MPEG-4 AVC

网络协议将编码好的视频流,从主播端推送到服务器,在服务器上有个运行了同样协议的服务端来接收这些网络包,从而得到里面的视频流,这个过程称为接流

服务端接到视频流之后,可以对视频流进行一定的处理,例如转码,也即从一个编码格式,转成另一种格式。因为观众使用的客户端千差万别,要保证他们都能看到直播。

流处理完毕之后,就可以等待观众的客户端来请求这些视频流。观众的客户端请求的过程称为拉流

如果有非常多的观众,同时看一个视频直播,那都从一个服务器上拉流,压力太大了,因而需要一个视频的分发网络,将视频预先加载到就近的边缘节点,这样大部分观众看的视频,是从边缘节点拉取的,就能降低服务器的压力。

所以整个直播流程,就可分为主播端采样编码推流,服务器接流处理分发,观众客户端拉流解码播放。

image-20260531151721013

编码流程

视频序列分成三种帧。

  • I帧,也称关键帧。里面是完整的图片,只需要本帧数据,就可以完成解码。
  • P帧,前向预测编码帧。P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面,叠加上和本帧定义的差别,生成最终画面。
  • B帧,双向预测内插编码帧。B帧记录的是本帧与前后帧的差别。要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的数据与本帧数据的叠加,取得最终的画面。

I 帧(Intra-coded picture,帧内编码帧)

  • 别名:关键帧(Keyframe)。
  • 特点:它是一张完整的、独立的图片,类似于一张高质量的 JPEG 照片。
  • 压缩方式:只进行“帧内压缩”(只去除一张图片内部的冗余信息),不依赖任何其他画面。
  • 作用:它是视频序列的“锚点”。当你在播放器里拖动进度条快进时,播放器必须先找到最近的 I 帧才能开始解码渲染。

P 帧(Predictive-coded picture,前向预测编码帧)

  • 别名:差别帧。
  • 特点:它不记录完整的图片,而只记录自己与前一个 I 帧(或前一个 P 帧)的“差异”和运动矢量
  • 压缩方式:帧间压缩(向前参考)。
  • 作用:由于大多数视频相邻两帧的画面变化很小(比如只有人在动,背景没动),P 帧通过只存储变化的部分,数据量通常只有 I 帧的 1/2 到 1/4,大大节省了空间。

B 帧(Bidirectionally predictive-coded picture,双向预测编码帧)

  • 别名:双向参考帧。
  • 特点:它是压缩率最高的帧。它不仅参考前面已经出现的画面,还要参考后面即将出现的画面,通过两头对比,计算出自己的画面。
  • 压缩方式:帧间压缩(双向参考)。
  • 作用:B 帧只记录极少的运动变化信息,数据量极小,通常只有 I 帧的 1/10 左右。

I帧最完整,B帧压缩率最高,而压缩后帧的序列,应该是在IBBP的间隔出现的。这就是通过时序进行编码

image-20260531155913719

在一帧中,分成多个片,每个片中分成多个宏块,每个宏块分成多个子块,这样将一张大的图分解成一个个小块,可以方便进行空间上的编码。尽管时空非常立体地组成了一个序列,但是总归还是要压缩成一个二进制流。这个流是有结构的,是一个个的网络提取层单元NALUNetwork Abstraction Layer Unit)。变成这种格式就是为了传输,因为网络上的传输,默认的是一个个的包,因而这里也就分成了一个个的单元。

每一个NALU首先是一个起始标识符,用于标识NALU之间的间隔;然后是NALU的头,里面主要配置了NALU的类型;最终Payload里面是NALU承载的数据。

在NALU头里面,主要的内容是类型NAL Type

  • 0x07表示SPS,是序列参数集, 包括一个图像序列的所有信息,如图像尺寸、视频格式等。
  • 0x08表示PPS,是图像参数集,包括一个图像的所有分片的所有相关信息,包括图像类型、序列号等

image-20260531155954397

在传输视频流之前,必须要传输这两类参数,不然无法解码。为了保证容错性,每一个I帧前面,都会传一遍这两个参数集合。

如果NALU Header里面的表示类型是SPS或者PPS,则Payload中就是真正的参数集的内容。

如果类型是帧,则Payload中才是正的视频数据,当然也是一帧一帧存放的,前面说了,一帧的内容还是挺多的,因而每一个NALU里面保存的是一片。对于每一片,到底是I帧,还是P帧,还是B帧,在片结构里面也有个Header,这里面有个类型,然后是片的内容。

这样,整个格式就出来了,一个视频,可以拆分成一系列的帧,每一帧拆分成一系列的片,每一片都放在一个NALU里面,NALU之间都是通过特殊的起始标识符分隔,在每一个I帧的第一片前面,要插入单独保存SPS和PPS的NALU,最终形成一个长长的NALU序列

推流流程

使用RTMP协议推送网络包。RTMP是基于TCP的,因而肯定需要双方建立一个TCP的连接。在有TCP的连接的基础上,还需要建立一个RTMP的连接,也即在程序里面,你需要调用RTMP类库的Connect函数,显示创建一个连接。

RTMP也需要先简历连接,协商本版号和时间戳等信息。

客户端发送C0、C1、 C2,服务器发送S0、 S1、 S2。

首先,客户端发送C0表示自己的版本号,不必等对方的回复,然后发送C1表示自己的时间戳。

服务器只有在收到C0的时候,才能返回S0,表明自己的版本号,如果版本不匹配,可以断开连接。

服务器发送完S0后,也不用等什么,就直接发送自己的时间戳S1。客户端收到S1的时候,发一个知道了对方时间戳的ACK C2。同理服务器收到C1的时候,发一个知道了对方时间戳的ACK S2。于是,握手完成。

握手之后,双方需要互相传递一些控制信息,例如Chunk块的大小、窗口大小等。

真正传输数据的时候,还是需要创建一个流Stream,然后通过这个Stream来推流publish。推流的过程,就是将NALU放在Message里面发送,这个也称为RTMP Packet包。Message的格式就像这样。

image-20260531180233027

发送的时候,去掉NALU的起始标识符。RTMP在收发数据的时候并不是以Message为单位的,而是把Message拆分成Chunk发送,而且必须在一个Chunk发送完成之后,才能开始发送下一个Chunk。每个Chunk中都带有Message ID,表示属于哪个Message,接收端也会按照这个ID将Chunk组装成Message。

连接的时候,设置的Chunk块大小就是指这个Chunk。将大的消息变为小的块再发送,可以在低带宽的情况下,减少网络拥塞。

假设一个视频的消息长度为307,但是Chunk大小约定为128,于是会拆分为三个Chunk。

第一个Chunk的Type=0,表示Chunk头是完整的;头里面Timestamp为1000,总长度Length 为307,类型为9,是个视频,Stream ID为12346,正文部分承担128个字节的Data。

第二个Chunk也要发送128个字节,Chunk头由于和第一个Chunk一样,因此采用Chunk Type=3,表示头一样就不再发送了。

第三个Chunk要发送的Data的长度为307-128-128=51个字节,还是采用Type=3。

image-20260531180615089

拉流流程

看直播的观众就可以通过RTMP协议从流媒体服务器上拉取,但是这么多的用户量,都去同一个地方拉取,服务器压力会很大,而且用户分布在全国甚至全球,如果都去统一的一个地方下载,也会时延比较长,需要有分发网络。

分发网络分为中心边缘两层。边缘层服务器部署在全国各地及横跨各大运营商里,和用户距离很近。中心层是流媒体服务集群,负责内容的转发。智能负载均衡系统,根据用户的地理位置信息,就近选择边缘服务器,为用户提供推/拉流服务。中心层也负责转码服务,例如,把RTMP协议的码流转换为HLS码流。

类似地,客户端拉流被,客户端通过RTMP协议拉取,然后组合为NALU,解码成视频格式进行播放。

P2P协议

无论是HTTP的方式,还是FTP的方式,都有一个比较大的缺点,就是难以解决单一服务器的带宽压力, 因为它们使用的都是传统的客户端服务器的方式。

后来,一种创新的、称为P2P的方式流行起来。P2P就是peer-to-peer。资源开始并不集中地存储在某些设备上,而是分散地存储在多台设备上。这些设备我们姑且称为peer。

想要下载一个文件的时候,你只要得到那些已经存在了文件的peer,并和这些peer之间,建立点对点的连接,而不需要到中心服务器上,就可以就近下载文件。一旦下载了文件,你也就成为peer中的一员,你旁边的那些机器,也可能会选择从你这里下载文件,所以当你使用P2P软件的时候,例如BitTorrent,往往能够看到,既有下载流量,也有上传的流量,也即你自己也加入了这个P2P的网络,自己从别人那里下载,同时也提供给其他人下载。可以想象,这种方式,参与的人越多,下载速度越快。

通过.torrent文件,也就是种子,知道文件信息。.torrent文件由两部分组成,分别是:announcetracker URL)和文件信息

文件信息里面有这些内容。

  • info区:这里指定的是该种子有几个文件、文件有多长、目录结构,以及目录和文件的名字。
  • Name字段:指定顶层目录名字。
  • 每个段的大小:BitTorrent(简称BT)协议把一个文件分成很多个小段,然后分段下载。
  • 段哈希值:将整个种子中,每个段的SHA-1哈希值拼在一起。

下载时,BT客户端首先解析.torrent文件,得到tracker地址,然后连接tracker服务器。tracker服务器回应下载者的请求,将其他下载者(包括发布者)的IP提供给下载者。下载者再连接其他下载者,根据.torrent文件,两者分别对方告知自己已经有的块,然后交换对方没有的数据。此时不需要其他服务器参与,并分散了单个线路上的数据流量,因此减轻了服务器的负担。

下载者每得到一个块,需要算出下载块的Hash验证码,并与.torrent文件中的对比。如果一样,则说明块正确,不一样则需要重新下载这个块。这种规定是为了解决下载内容的准确性问题。

这种方式特别依赖tracker。tracker需要收集下载者信息的服务器,并将此信息提供给其他下载者,使下载者们相互连接起来,传输数据。虽然下载的过程是非中心化的,但是加入这个P2P网络的时候,都需要借助tracker中心服务器,这个服务器是用来登记有哪些用户在请求哪些资源。

所以,这种工作方式有一个弊端,一旦tracker服务器出现故障或者线路遭到屏蔽,BT工具就无法正常工作了。

DHT去中心化网络

后来就有了一种叫作DHTDistributed Hash Table)的去中心化网络。每个加入这个DHT网络的人,都要负责存储这个网络里的资源信息和其他成员的联系信息,相当于所有人一起构成了一个庞大的分布式存储数据库。

有一种著名的DHT协议,叫Kademlia协议

任何一个BitTorrent启动之后,它都有两个角色。一个是peer,监听一个TCP端口,用来上传和下载文件,这个角色表明,我这里有某个文件。另一个角色DHT node,监听一个UDP的端口,通过这个角色,这个节点加入了一个DHT的网络。在DHT网络里面,每一个DHT node都有一个ID。这个ID是一个很长的串。每个DHT node都有责任掌握一些知识,也就是文件索引,也即它应该知道某些文件是保存在哪些节点上。它只需要有这些知识就可以了,而它自己本身不一定就是保存这个文件的节点。

数据中心

数据中心里面是服务器。服务器被放在一个个叫作机架Rack)的架子上面。数据中心的入口和出口也是路由器,由于在数据中心的边界,就像在一个国家的边境,称为边界路由器Border Router)。为了高可用,边界路由器会有多个。

一般家里只会连接一个运营商的网络,而为了高可用,为了当一个运营商出问题的时候,还可以通过另外一个运营商来提供服务,所以数据中心的边界路由器会连接多个运营商网络。

数据中心里面往往有非常多的机器,当塞满一机架的时候,需要有交换机将这些服务器连接起来,可以互相通信。这些交换机往往是放在机架顶端的,所以经常称为TORTop Of Rack交换机

当一个机架放不下的时候,就需要多个机架,还需要有交换机将多个机架连接在一起。这些交换机对性能的要求更高,带宽也更大。这些交换机称为汇聚层交换机Aggregation Layer)。

image-20260531211311654

数据中心里面的每一个连接都是需要考虑高可用的。这里首先要考虑的是,如果一台机器只有一个网卡,上面连着一个网线,接入到TOR交换机上。如果网卡坏了,或者不小心网线掉了,机器就上不去了。所以,需要至少两个网卡、两个网线插到TOR交换机上,但是两个网卡要工作得像一张网卡一样,这就是常说的网卡绑定bond)。

这就需要服务器和交换机都支持一种协议LACPLink Aggregation Control Protocol)。它们互相通信,将多个网卡聚合称为一个网卡,多个网线聚合成一个网线,在网线之间可以进行负载均衡,也可以为了高可用作准备。

网卡有了高可用保证,但交换机还有问题。如果一个机架只有一个交换机,它挂了,那整个机架都不能上网了。因而TOR交换机也需要高可用,同理接入层和汇聚层的连接也需要高可用性,也不能单线连着

最传统的方法是,部署两个接入交换机、两个汇聚交换机。服务器和两个接入交换机都连接,接入交换机和两个汇聚都连接,当然这样会形成环,所以需要启用STP协议,去除环,但是这样两个汇聚就只能一主一备了。

image-20260531211434589

另一种方法是,将多个交换机形成一个逻辑的交换机,服务器通过多根线分配连到多个接入层交换机上,而接入层交换机多根线分别连接到多个交换机上,并且通过堆叠的私有协议,形成双活的连接方式。

image-20260531211452050

汇聚层将大量的计算节点相互连接在一起,形成一个集群。在这个集群里面,服务器之间通过二层互通,这个区域常称为一个PODPoint Of Delivery),有时候也称为一个可用区Available Zone)。

当节点数目再多的时候,一个可用区放不下,需要将多个可用区连在一起,连接多个可用区的交换机称为核心交换机

VPN

有的公司有多个数据中心,需要将多个数据中心连接起来,或者需要办公室和数据中心连接起来。这该怎么办呢?

  • 第一种方式是走公网,但是公网太不安全,你的隐私可能会被别人偷窥。
  • 第二种方式是租用专线的方式把它们连起来,这是土豪的做法,需要花很多钱。
  • 第三种方式是用VPN来连接,这种方法比较折中,安全又不贵。

VPN,全名Virtual Private Network虚拟专用网,就是利用开放的公众网络,建立专用数据传输通道,将远程的分支机构、移动办公人员等连接起来。

image-20260531212927889

VPN工作方式

VPN通过隧道技术在公众网络上仿真一条点到点的专线,是通过利用一种协议来传输另外一种协议的技术,这里面涉及三种协议:乘客协议隧道协议承载协议

IPsec VPN。这是基于IP协议的安全隧道协议,为了保证在公网上面信息的安全,因而采取了一定的机制保证安全性。

  • 机制一:私密性,防止信息泄露给未经授权的个人,通过加密把数据从明文变成无法读懂的密文,从而确保数据的私密性。 前面讲HTTPS的时候,说过加密可以分为对称加密和非对称加密。对称加密速度快一些。而VPN一旦建立,需要传输大量数据,因而我们采取对称加密。但是同样,对称加密还是存在加密密钥如何传输的问题,这里需要用到因特网密钥交换(IKE,Internet Key Exchange)协议。
  • 机制二:完整性,数据没有被非法篡改,通过对数据进行hash运算,产生类似于指纹的数据摘要,以保证数据的完整性。
  • 机制三:真实性,数据确实是由特定的对端发出,通过身份认证可以保证数据的真实性。

image-20260531213609789

有了IPsec VPN之后,客户端发送的明文的IP包,都会被加上ESP头和IP头,在公网上传输,由于加密,可以保证不被窃取,到了对端后,去掉ESP的头,进行解密。