
作为一名程序员,不管是做后端开发、嵌入式开发还是前端开发,计算机网络都是绕不开的核心基础。我们每天用浏览器访问网页、用 IM 工具聊天、用服务器部署应用,背后都是计算机网络在默默支撑。从最初的单台独立计算机,到如今互联互通的互联网世界,网络的发展本质上是为了解决设备协同、数据共享的核心问题。这篇文章就从计算机网络的发展背景出发,带大家一步步认识网络的核心 —— 协议,搞懂为什么网络需要协议、协议是如何设计的,为后续深入学习 TCP/IP、Socket 编程打下基础。下面就让我们正式开始吧!

计算机刚诞生的时候,是以独立模式存在的,每一台计算机都是一个 “信息孤岛”。不同终端 A、B、C 各自存储客户数据,运行专属业务,比如终端 A 运行业务 1、终端 B 运行业务 2,一旦操作人员需要切换业务,就得物理移动到对应主机前操作,效率极低。此时的计算机只是单个的工具,无法发挥协同工作的价值。

随着计算机的普及,人们开始有了数据共享、业务互通的需求,于是就有了网络互联的雏形:将多台计算机连接在一起,为不同业务配置专用的服务器,比如小松专用计算机、小竹专用计算机,每个人可以在自己的独立计算机上自由切换业务 1、2、3,所有共享数据由服务器集中管理。这一步的改变,让计算机从 “单机工具” 变成了 “协同工具”,也是网络的核心价值体现 ——连接产生价值。

当连接的计算机数量越来越多,简单的互联已经满足不了需求,于是就有了局域网(LAN) 和广域网(WAN) 的概念。


这里要注意,局域网和广域网其实是相对概念,比如我们常说的 “内网”,对于整个互联网来说是局域网,但对于内网中的设备来说,就是一个完整的网络。而计算机网络的产生并不是偶然,因为计算机是人的工具,人需要协同工作,就注定了设备之间需要连接,网络的出现是技术发展的必然结果。
从独立模式到网络互联,再到局域网和广域网,每一步发展都围绕着一个核心:降低数据交互的成本,提升设备协同的效率。而要实现真正的互联互通,光有硬件连接还不够,还需要一套统一的 “沟通规则”—— 这就是协议。
生活中我们处处有协议:打电话时约定电话铃响 3 声没人接就挂掉,见面时约定握手表示友好,这些双方达成一致的规则,就是协议。计算机网络中的协议,本质上也是一样的,是计算机之间进行数据通信的约定和规则。
计算机之间的传输媒介是光信号和电信号,这些信号只能通过频率的高低、信号的强弱来表示 0 和 1 这样的二进制信息。要想用 0 和 1 传递文字、图片、视频等复杂信息,就必须约定好双方的数据格式:比如用多少个 01 组合表示一个字符,用什么标识一段数据的开始和结束,用什么方式验证数据是否传输错误。

举个简单的例子:如果主机 A 用频率高低表示 0 和 1,主机 B 用信号强弱表示 0 和 1,哪怕两者约定了 “传输 10 个字符就停止”,最终也无法正常通信 —— 就像一个人说中文,一个人说葡萄牙语,哪怕都遵守 “一句话说 10 个字” 的规则,也无法理解对方的意思。
所以,完善的协议必须是细致、统一的,不仅要约定通信的基本规则,还要约定数据的表示方式、传输方式、校验方式等,并且要求所有参与通信的设备都严格遵守。
我们身边的计算机设备,有着各种各样的 “出身”:
如果每个厂商都按照自己的规则设计通信方式,那么戴尔的电脑就无法和华为的服务器通信,Windows 系统就无法和 Linux 系统交换数据,整个网络世界就会回到 “各自为战” 的状态。
要解决这种设备异构的问题,就需要有权威的组织或机构站出来,制定一套全球通用的网络协议标准,让所有厂商、所有设备都遵循这套标准进行设计和生产。这就像全世界的交通规则都约定 “靠右行驶(部分国家靠左)”“红灯停绿灯行”,只有这样,不同的车辆、不同的驾驶员才能在同一条道路上安全行驶。
网络协议标准的制定,需要具备技术权威性、行业认可度,不是任何公司或组织都能制定的。能定制协议标准的主体主要分为五类,涵盖国际组织、区域组织、企业、民间团体和官方机构,各自在不同领域发挥着重要作用:
这类组织是网络协议标准的 “核心玩家”,制定的标准适用于全球范围,是互联网互联互通的基础。
这类组织主要为特定区域的通信技术发展制定标准,解决区域内的网络互联问题,代表有:
部分技术实力雄厚的企业,会在通用标准的基础上,针对细分领域自研协议栈,并进行定制化改动,这也是企业的核心竞争力。比如泰凌微,在低功耗蓝牙、ZigBee、Thread、Matter 等物联网协议领域深耕,自研了对应的软件协议栈,还将这些协议应用在智能电子价签、智能遥控、智能家居等物联网场景中。
企业定制的协议一般聚焦于特定场景,是对通用标准的补充,而非替代,最终还是会兼容全球通用标准。
这类团体并非官方组织,而是由全球的技术爱好者、工程师组成,专注于互联网协议的开发和推广,最具代表性的是IETF(互联网工程师任务组)。
IETF 是一个志愿组织,通过RFC(请求评论) 文档发布新的协议标准或取代旧的标准,我们熟知的TCP/IP 协议族,就是由 IETF 主导开发和推广的。IETF 的特点是开放、灵活,能快速响应互联网技术的发展,及时迭代协议标准,适应新的网络场景。
这类机构主要负责对通信技术、协议标准进行审查和监督,确保其符合公众利益和国家法规,代表是FCC(美国联邦通信委员会)。FCC 负责管理美国的无线电、电视、有线通信,对通信产品的技术特性、协议标准进行审查,确保产品的安全性和兼容性,间接推动了协议标准的规范化。
协议的本质也是软件,而软件设计的核心原则之一是模块化、解耦合,网络协议也遵循这个原则,被设计成层状结构,这就是协议分层。协议分层不是凭空设计的,而是为了解决协议设计和维护中的实际问题,我们先从一个生活中的例子,理解协议分层的好处。
我们打电话的过程,可以拆分成语言层和通信设备层两层协议:
这两层协议是解耦合的:
这样的设计,让每一层的修改都不会影响到其他层,降低了维护成本,也让协议的可扩展性更强。如果没有分层,把 “语言规则” 和 “设备规则” 混在一起,那么更换任何一个环节,都需要重新制定整套规则,效率极低。

打电话的例子只有两层协议,而计算机网络的通信场景更复杂,需要处理数据的封装、传输、路由、校验、应用等多个环节,因此网络协议需要分更多的层。
最经典的协议分层模型是OSI 七层模型,由 ISO 制定,将网络通信从逻辑上分为 7 层,每一层都有明确的功能和对应的物理设备,核心作用是帮助不同类型的主机实现可靠的数据传输。OSI 七层模型的最大优点是将服务、接口、协议三个概念明确区分,概念清晰、理论完整,为网络协议的设计提供了完整的框架。
OSI 七层模型的分层及核心功能如下:


虽然 OSI 七层模型理论上非常完善,但在工程实践中,会话层和表示层的功能很难直接接入到操作系统中,无法落地实现。因此,实际应用中我们采用的是TCP/IP 五层模型,而如果忽略物理层(硬件层面),只考虑软件层面,就成了TCP/IP 四层模型,这也是我们学习网络编程的核心模型。
TCP/IP 五层模型的分层及核心功能、对应设备如下,是我们后续学习的重点:

协议分层后,不同的网络设备实现的协议层也不同,这也是设备功能差异的核心原因:
当然这不是绝对的,现在很多网络设备都做了功能扩展,比如部分交换机支持网络层的转发,部分路由器支持传输层的端口转发,但其核心功能仍然对应着固定的协议层。
学到这里,我们已经知道协议是网络通信的规则,是分层设计的,但协议在代码层面到底是什么样的?其实用一句朴素的话总结:协议就是通信双方都认识的结构化数据类型。
我们可以用 C/C++ 的结构体来理解这个概念,因为操作系统的源代码一般都是用 C/C++ 编写的,网络协议的实现也不例外。
假设在网络协议的某一层,通信双方都定义了同一个 C 语言结构体:
// 通信双方共同约定的协议结构体
struct Protocol {
int a; // 字段1
int b; // 字段2
int c; // 字段3
char data[1024]; // 有效载荷
};主机 A 要给主机 B 发送数据,会创建这个结构体的实例,赋值后发送:
#include <stdio.h>
#include <string.h>
// 共同约定的协议结构体
struct Protocol {
int a;
int b;
int c;
char data[1024];
};
int main() {
// 主机A构造协议数据
struct Protocol send_data;
send_data.a = 10;
send_data.b = 20;
send_data.c = 30;
strcpy(send_data.data, "Hello, Network Protocol!");
// 将结构体数据发送到网络(后续通过Socket实现,此处仅示意)
send_to_network(&send_data, sizeof(send_data));
return 0;
}主机 B 接收到数据后,用同一个结构体来解析:
#include <stdio.h>
// 与主机A完全相同的协议结构体
struct Protocol {
int a;
int b;
int c;
char data[1024];
};
int main() {
struct Protocol recv_data;
// 从网络接收数据(后续通过Socket实现,此处仅示意)
recv_from_network(&recv_data, sizeof(recv_data));
// 解析数据
printf("a = %d\n", recv_data.a); // 输出a = 10
printf("b = %d\n", recv_data.b); // 输出b = 20
printf("c = %d\n", recv_data.c); // 输出c = 30
printf("data = %s\n", recv_data.data); // 输出data = Hello, Network Protocol!
return 0;
} 因为主机 A 和主机 B 使用了完全相同的结构体类型,所以主机 B 能准确识别并提取出a=10、b=20、c=30以及有效载荷数据。这种双方共同遵守的结构化数据定义,就是协议的本质 —— 共识。
协议是分层的,因此每一层都有自己的协议结构体(报头),同层之间互相认识对方的协议,不同层之间通过 “接口” 传递数据。
比如 TCP/IP 五层模型中,应用层有应用层的协议结构体(如 HTTP 的请求头),传输层有传输层的协议结构体(如 TCP 的报头),网络层有网络层的协议结构体(如 IP 的报头),数据链路层有数据链路层的协议结构体(如以太网的帧头)。
当数据在网络中传输时,会经历封装和解包的过程:
这个过程就像我们寄快递:
其中,快递单、物流单、路由单、面单就是各层的协议报头,要寄的东西就是有效载荷,而报头 + 有效载荷就是每一层的报文。
不同的协议层,对封装后的数据包有不同的称谓,这是网络学习中需要记住的基础概念:
这些称谓的差异,本质上是因为各层的协议报头和功能不同,但核心都是 “结构化数据 + 有效载荷”。
这篇文章是计算机网络的入门内容,搞懂这些基础概念,才能为后续学习局域网通信原理、IP 地址、MAC 地址、端口号、TCP/UDP 协议、Socket 编程打下基础。下一篇文章,我们会深入讲解局域网的通信原理,搞懂 MAC 地址、IP 地址的区别,以及数据在局域网中是如何传输的。 我后续会结合 C/C++ 的 Socket 编程代码,从实践角度讲解网络协议的使用,让大家真正理解 “协议在代码中如何实现”。如果这篇文章对你有帮助,欢迎点赞、收藏、关注,一起学习计算机网络!