目录
[1.1 网络的核心价值](#1.1 网络的核心价值)
[1.2 协议:设备通信的"共同语言"](#1.2 协议:设备通信的“共同语言”)
二、协议分层模型:从OSI到TCP/IP
[2.1 为什么需要分层?](#2.1 为什么需要分层?)
[2.2 OSI模型](#2.2 OSI模型)
[2.3 TCP/IP模型](#2.3 TCP/IP模型)
[2.4 分层通信的核心:封装与解包](#2.4 分层通信的核心:封装与解包)
三、网络通信的三大核心标识
[3.1 IP地址:跨网络的主机身份证](#3.1 IP地址:跨网络的主机身份证)
[3.2 MAC地址:局域网内的设备标识](#3.2 MAC地址:局域网内的设备标识)
[3.3 端口号:主机内的进程门牌号](#3.3 端口号:主机内的进程门牌号)
[3.4 关键结论:IP+端口号=Socket](#3.4 关键结论:IP+端口号=Socket)
四、传输层核心协议:TCP与UDP
[4.1 TCP:可靠传输](#4.1 TCP:可靠传输)
[4.2 UDP:高效传输](#4.2 UDP:高效传输)
[4.3 协议选型建议](#4.3 协议选型建议)
[五、网络编程预备:字节序与Socket API](#五、网络编程预备:字节序与Socket API)
[5.1 网络字节序:跨主机的字节约定](#5.1 网络字节序:跨主机的字节约定)
[5.2 Socket核心API入门](#5.2 Socket核心API入门)
[5.3 sockaddr结构体:通用地址接口](#5.3 sockaddr结构体:通用地址接口)
六、总结
一、网络的本质:跨主机的进程间通信
在Linux系统中,我们之前学过进程间通信(IPC)的多种方式(管道、共享内存等),但这些方式有一个共同的限制------只能在同一台主机内的进程间使用。而网络的出现,本质是将"进程间通信"延伸到了跨主机场景:无论两台主机相隔千里,只要接入网络,它们的进程就能像在同一台机器上一样交换数据。
1.1 网络的核心价值
- 资源共享:一台服务器的数据库、文件可以被多台客户端访问;
- 分布式协作:不同主机的进程分工完成复杂任务(如Web服务器+数据库服务器);
- 突破地理限制:远程登录、视频通话等场景本质都是跨主机进程通信。
1.2 协议:设备通信的"共同语言"
计算机之间的传输媒介是光信号、电信号(本质是0和1的组合),要让这些0和1被对方理解,就需要一套"约定"------这就是网络协议。
举个生活中的例子:打电话时,"铃响3声内接听"是双方的约定;网络通信中,"数据开头4字节表示数据长度"就是一种协议约定。
协议的核心作用:
- 统一数据格式:规定字段的顺序、长度、含义;
- 统一交互逻辑:规定"如何建立连接""如何确认接收""如何处理错误";
- 屏蔽设备差异:无论硬件(Intel/AMD)、系统(Linux/Windows),遵守同一协议就能通信。
制定协议的权威组织包括IEEE(制定局域网标准)、IETF(制定TCP/IP协议族)、ISO(制定OSI模型)等,它们确保了全球设备的通信兼容性。
二、协议分层模型:从OSI到TCP/IP
协议本质是软件,为了模块化设计、降低维护成本,被设计为分层结构------每层只负责特定功能,通过接口与上下层交互,无需关心其他层的实现。
2.1 为什么需要分层?
分层的核心是"解耦"。比如:
- 更换局域网传输介质(从网线到WiFi),只需修改物理层和数据链路层,无需改动应用层(如HTTP协议);
- 应用层从HTTP切换到FTP,只需修改应用层逻辑,传输层(TCP)和网络层(IP)可以完全复用。
2.2 OSI模型
OSI将网络通信从逻辑上划分为七层,每层职责单一、边界清晰,自上而下依次为:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。每层仅与直接相邻的上下层交互,通过"服务接口"提供功能,屏蔽底层实现细节。
| 分层(从顶到下) | 核心功能 | 关键作用与示例 |
|---|---|---|
| 7. 应用层 | 为特定应用提供通信协议,直接面向用户需求 | 如HTTP(网页浏览)、FTP(文件传输)、SMTP(邮件),是用户进程与网络的"交互入口"; |
| 6. 表示层 | 负责数据格式转换、加密/解密、压缩/解压缩,统一网络数据格式 | 例如将本地主机的二进制数据转换为网络标准格式,或对敏感数据(如登录密码)进行加密处理; |
| 5. 会话层 | 管理通信连接(建立、维护、断开),控制数据传输的逻辑通路 | 例如决定何时建立连接、连接超时时间、何时释放连接,确保通信双方的会话同步; |
| 4. 传输层 | 负责两台主机间的端到端数据传输,保证数据的可靠/高效传递 | 与TCP/IP传输层功能类似,提供流量控制、差错校验,对应TCP(可靠)、UDP(高效)等协议; |
| 3. 网络层 | 地址管理与路由选择,确定数据从源主机到目标主机的跨网络传输路径 | 与TCP/IP网络层一致,通过IP地址标识主机,通过路由器规划传输路线; |
| 2. 数据链路层 | 局域网内数据帧的传输与识别,处理帧同步、冲突检测、差错校验 | 与TCP/IP数据链路层功能一致,通过MAC地址标识局域网设备,对应以太网、WiFi等协议; |
| 1. 物理层 | 定义光/电信号的传输规则,规定传输介质(网线、光纤)和连接器的物理规格 | 与TCP/IP物理层一致,负责将0/1比特流转换为实际的电信号或光信号; |
2.3 TCP/IP模型
OSI七层模型是理论上的完美框架,但实际工程中落地的是TCP/IP五层模型(或简化为四层),每层的功能、核心协议、代表设备如下:
2.3.1 物理层(最底层)
- 功能:负责将0和1转换为光/电信号,定义传输介质的规格(网线、光纤、电磁波);
- 核心:无协议,仅处理硬件层面的信号传输;
- 代表设备:集线器(Hub)、网线、网卡的物理接口。
2.3.2 数据链路层
- 功能:局域网内的设备识别与数据帧传输,处理帧同步、冲突检测、差错校验;
- 核心协议:以太网协议、WiFi协议;
- 核心标识:MAC地址(网卡出厂时固化的唯一标识);
- 代表设备:交换机(Switch)、网卡驱动。
2.3.3 网络层
- 功能:跨网络的地址管理与路由选择,确定数据从源主机到目标主机的传输路径;
- 核心协议:IP协议(IPv4/IPv6)、ICMP协议(网络差错报告);
- 核心标识:IP地址(跨网络的主机唯一标识);
- 代表设备:路由器(Router)。
2.3.4 传输层
- 功能:主机内进程间的可靠传输,处理数据的分段、重组、流量控制;
- 核心协议:TCP(可靠传输)、UDP(高效传输);
- 核心标识:端口号(主机内进程的唯一标识);
- 运行载体:操作系统内核(Linux内核实现TCP/UDP协议栈)。
2.3.5 应用层(最上层)
- 功能:针对特定应用场景的协议约定,如文件传输、网页浏览、邮件发送;
- 核心协议:HTTP(网页)、FTP(文件传输)、SMTP(邮件)、Telnet(远程登录);
- 运行载体:用户进程(如浏览器、FTP客户端)。
注:TCP/IP四层模型是将物理层和数据链路层合并为"网络接口层",核心逻辑与五层模型一致。

2.4 分层通信的核心:封装与解包
数据从应用层发送到网络的过程,是逐层封装 ;到达目标主机后,是逐层解包,这是网络通信的核心流程:
封装过程(发送端):
- 应用层:用户数据(如"Hello World")加上应用层头部(如HTTP头部,包含请求方法、目标路径);
- 传输层:将应用层数据作为"有效载荷",加上传输层头部(如TCP头部,包含源端口、目标端口),形成"段";
- 网络层:将传输层段作为有效载荷,加上网络层头部(如IP头部,包含源IP、目标IP),形成"数据报";
- 数据链路层:将网络层数据报作为有效载荷,加上链路层头部(如以太网头部,包含源MAC、目标MAC)和尾部(差错校验字段),形成"帧";
- 物理层:将帧转换为光/电信号,通过传输介质发送。
解包过程(接收端):
- 物理层:接收光/电信号,转换为帧,交给数据链路层;
- 数据链路层:校验尾部、剥离链路层头部,提取数据报,交给网络层;
- 网络层:校验IP头部、剥离网络层头部,提取段,交给传输层;
- 传输层:校验TCP/UDP头部、重组分段(若有),提取应用层数据,交给应用层;
- 应用层:解析应用层头部,处理用户数据(如浏览器渲染网页)。

三、网络通信的三大核心标识
要实现"跨主机进程通信",需要三层标识:IP地址(找主机)、MAC地址(找局域网设备)、端口号(找进程)。
3.1 IP地址:跨网络的主机身份证
- 定义:IP协议中标识网络中唯一主机的地址,IPv4为32位整数(4字节),用点分十进制表示(如192.168.0.1);
- 作用:跨网络传输时,路由器通过IP地址确定数据的转发路径(类似快递的收件地址);
- 特点:IP地址在整个跨网络传输过程中保持不变,是"最终目标地址"。
3.2 MAC地址:局域网内的设备标识
- 定义:数据链路层标识局域网内设备的地址,48位整数(6字节),用十六进制+冒号表示(如08:00:27:03:fb:19);
- 作用:局域网内数据转发时,交换机通过MAC地址确定数据的下一跳设备(类似快递的小区楼栋号);
- 特点:MAC地址在跨网络传输时不断变化,每经过一个路由器,都会重新封装链路层头部,更新源MAC和目标MAC。
3.3 端口号:主机内的进程门牌号
- 定义:传输层标识主机内唯一网络进程的地址,16位整数(范围0-65535);
- 分类:
- 0-1023:知名端口号(HTTP=80,FTP=21,SSH=22);
- 1024-65535:动态端口号(客户端进程由操作系统分配);
- 作用:数据到达目标主机后,操作系统通过端口号将数据交给对应的进程(类似快递的房门号);
- 特点:一个端口号只能被一个进程绑定,但一个进程可以绑定多个端口号。
3.4 关键结论:IP+端口号=Socket
- 单独的IP地址只能找到主机,单独的端口号只能找到主机内的进程,二者结合才能唯一标识"互联网中的某个进程";
- 这种"IP地址+端口号"的组合,称为Socket(套接字),是网络编程的核心标识;
- 通信的本质:两个Socket之间的数据交互,用"源IP+源端口+目标IP+目标端口"的四元组,可以唯一标识互联网中的一次通信。
四、传输层核心协议:TCP与UDP
传输层的核心是TCP和UDP协议,二者是网络编程中最常用的协议,定位完全不同:
4.1 TCP:可靠传输
- 核心特性:有连接、可靠传输、面向字节流;
- 有连接:通信前需建立三次握手,通信后需四次挥手;
- 可靠传输:通过序列号、确认应答、重传机制、流量控制、拥塞控制,确保数据不丢失、不重复、按序到达;
- 面向字节流:数据无边界,像水流一样连续传输(需应用层自行定义数据边界,也就是序列化);
- 适用场景:文件传输(FTP)、网页浏览(HTTP)、邮件发送(SMTP)等对可靠性要求高的场景。
4.2 UDP:高效传输
- 核心特性:无连接、不可靠传输、面向数据报;
- 无连接:通信前无需建立连接,直接发送数据;
- 不可靠传输:无确认应答、无重传机制,数据可能丢失、重复、乱序;
- 面向数据报:数据有明确边界,每次发送都是一个独立的数据报(接收方一次接收一个完整数据报);
- 适用场景:实时通信(视频通话、语音聊天)、游戏数据传输、广播/组播等对实时性要求高的场景。
4.3 协议选型建议
- 优先选TCP:数据不能丢失、需要顺序保证(如文件、支付数据);
- 优先选UDP:追求低延迟、允许少量数据丢失(如实时音视频、游戏);
- 注意:UDP的"不可靠"是指传输层不保证,可通过应用层实现可靠性(如添加序列号、重传机制)。
五、网络编程预备:字节序与Socket API
Linux网络编程的核心是Socket接口,而使用Socket前,必须先解决字节序问题,否则会出现数据解析错误。
5.1 网络字节序:跨主机的字节约定
- 主机字节序:不同CPU的字节存储顺序(大端/小端),如x86架构是小端,PowerPC是大端;
- 网络字节序:TCP/IP协议规定的统一字节序------大端字节序(低地址存储高字节);
- 为什么需要转换?:如果发送方是小端主机,直接发送数据会导致接收方(可能是大端主机)解析错误,因此需将主机字节序转换为网络字节序发送,接收方再转换为主机字节序。
核心转换函数(需包含<arpa/inet.h>):
htons:host to network short(16位端口号转换);htonl:host to network long(32位IP地址转换);ntohs:network to host short(16位端口号还原);ntohl:network to host long(32位IP地址还原)。
示例:将端口号80转换为网络字节序:
c
uint16_t port = 80;
uint16_t net_port = htons(port);
5.2 Socket核心API入门
Socket是Linux内核提供的网络编程接口,本质是一个文件描述符(与文件、管道的描述符统一管理),核心API如下:
1. 创建Socket(socket)
c
int socket(int domain, int type, int protocol);
domain:地址族(AF_INET=IPv4,AF_INET6=IPv6);type:套接字类型(SOCK_STREAM=TCP,SOCK_DGRAM=UDP);protocol:协议(0=默认,由前两个参数推导);- 返回值:成功返回Socket文件描述符,失败返回-1。
示例:创建TCP Socket:
c
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
2. 绑定地址(bind)
c
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
- 作用:将Socket与"IP+端口号"绑定(服务器端必须绑定,客户端可选);
addr:通用地址结构体指针(需强制转换为struct sockaddr *);addrlen:地址结构体长度。
3. 开始监听(listen,仅TCP服务器)
c
int listen(int sockfd, int backlog);
- 作用:将主动套接字(客户端)转换为被动套接字(服务器),开始接收连接请求;
backlog:连接请求队列的最大长度。
4. 接收连接(accept,仅TCP服务器)
c
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
- 作用:从连接队列中取出一个连接,创建新的Socket用于通信;
- 返回值:成功返回新的通信Socket描述符,失败返回-1。
5. 建立连接(connect,仅TCP客户端)
c
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
- 作用:向服务器发起TCP连接请求;
addr:服务器的"IP+端口号"地址结构体。
5.3 sockaddr结构体:通用地址接口
Socket API支持多种地址族(IPv4、IPv6、UNIX域),因此提供了通用的struct sockaddr结构体,编程时需根据地址族使用具体的结构体(如IPv4用struct sockaddr_in),再强制转换为struct sockaddr *。
IPv4地址结构体(struct sockaddr_in):
c
struct sockaddr_in {
sa_family_t sin_family; // 地址族(AF_INET)
in_port_t sin_port; // 端口号(网络字节序)
struct in_addr sin_addr; // IP地址(32位整数,网络字节序)
unsigned char sin_zero[8]; // 填充字段,需置0
};
struct in_addr {
in_addr_t s_addr; // IPv4地址(网络字节序)
};
示例:初始化服务器地址结构体:
c
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8080); // 端口号转换为网络字节序
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 绑定所有网卡IP
六、总结
网络编程的核心逻辑可以概括为:用Socket标识跨网络进程,通过协议分层实现数据的封装与传输,用TCP/UDP保证传输的可靠性或高效性。
本文覆盖了网络编程的基础概念,后续会深入讲解:
- 基础Socket编程实战;
- TCP/UDP协议细节(三次握手、四次挥手、滑动窗口、重传机制);
- 并发网络编程(多进程、多线程、IO复用);
- 应用层协议实战。