
🎬 个人主页 :艾莉丝努力练剑
❄专栏传送门 :《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》
《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》
⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平
🎬 艾莉丝的简介:

文章目录
- [1 ~> 理解"通信"的本质 ------ 跨主机的进程间通信(IPC)](#1 ~> 理解“通信”的本质 —— 跨主机的进程间通信(IPC))
- [2 ~> 数据包的"通关文迭" ------ 封装、解封装与分用](#2 ~> 数据包的“通关文迭” —— 封装、解封装与分用)
-
- [2.1 封装(Encapsulation):各司其职的报头](#2.1 封装(Encapsulation):各司其职的报头)
- [2.2 解封装与分用(Demultiplexing)](#2.2 解封装与分用(Demultiplexing))
- [3 ~> 跨网络传输的"两张地图" :IP 与 MAC 的配合](#3 ~> 跨网络传输的“两张地图” :IP 与 MAC 的配合)
-
- [3.1 核心跳转逻辑](#3.1 核心跳转逻辑)
- [3.2 IP地址的意义](#3.2 IP地址的意义)
- [3.3 对比IP地址和Mac地址的区别](#3.3 对比IP地址和Mac地址的区别)
- [3.4 IP网络的意义和网络通信的宏观流程](#3.4 IP网络的意义和网络通信的宏观流程)
- [4 ~> Socket(插座) 编程的"入场券"](#4 ~> Socket(插座) 编程的“入场券”)
-
- [4.1 端口号(Port)](#4.1 端口号(Port))
-
- [4.1.1 端口号范围划分](#4.1.1 端口号范围划分)
- [4.1.2 细节](#4.1.2 细节)
- [4.2 理解"端口号"和"进程ID"](#4.2 理解"端口号"和"进程ID")
-
- [4.2.1 不是所有的进程都要进行网络通信!](#4.2.1 不是所有的进程都要进行网络通信!)
- [4.2.2 10086例子](#4.2.2 10086例子)
- [4.3 理解源端口号和目的端口号](#4.3 理解源端口号和目的端口号)
- [4.4 理解源IP地址和目的IP地址](#4.4 理解源IP地址和目的IP地址)
- [4.5 理解Socket](#4.5 理解Socket)
- [4.6 字节序(Endianness)的硬标准](#4.6 字节序(Endianness)的硬标准)
- [5 ~> 总结](#5 ~> 总结)
- 结尾

1 ~> 理解"通信"的本质 ------ 跨主机的进程间通信(IPC)
在底层开发者眼中,网络不仅是网线和信号,而是操作系统的延伸。
不仅仅是发消息:我们在主机 A 上启动 QQ 进程,在主机 B 上也启动 QQ。A 发消息给 B,本质上是 A 主机上的进程将数据交给内核,通过网络协议栈传给 B 主机的内核,再由 B 的内核交付给对应的进程。
定位公式:
-
IP 地址:在公网中标识唯一的一台主机。
-
端口号(Port):在主机内部标识唯一的一个进程。
-
逻辑基点 :
IP + Port = 全球唯一的进程。就像"10086(IP)+ 9527 号话务员(Port)",缺一不可。
2 ~> 数据包的"通关文迭" ------ 封装、解封装与分用
数据在每一层都有它对应的"名号",就像我们在不同阶段有不同的称呼:
2.1 封装(Encapsulation):各司其职的报头
每一层都要加报头,是因为每一层软件层都要解决特定的问题:
应用层(请求/应答):处理业务逻辑(如 HTTP 报头)。
传输层(数据段 Segment):封装源/目端口,解决数据该给谁的问题(TCP/UDP)。
网络层(数据报 Datagram):封装源/目 IP,解决路径选择和主机定位问题。
链路层(数据帧 Frame):封装 MAC 地址,解决局域网内相邻节点的交付问题。
类比:这就像嵌套的快递盒。最里层是信件,套上应用层信封,装入传输层纸箱,塞进网络层集装箱,最后挂上链路层的物流拖车。
2.2 解封装与分用(Demultiplexing)
接收端收到比特流后,会自底向上"剥壳"。
- 标识的力量 :每一层的报头里都有一个"下一层是谁"的标识位。例如 IP 报头里写着"这是 TCP",网络层就会把去掉报头后的内容传给 TCP 协议。这种根据报头标识准确送往上一层的过程,就叫分用。

3 ~> 跨网络传输的"两张地图" :IP 与 MAC 的配合
这是最核心的逻辑,也是最容易在面试或实战中出错的地方。
-
IP 地址(全局路径):它是逻辑地址,负责"终点导航"。它的意义在于屏蔽了底层不同局域网(以太网、令牌环网、无线 LAN 等)的差异。在 IP 层看来,全世界都是 IP 报文,这就是"一切皆 IP"的思想。
-
MAC 地址(局部跳转):它是物理地址,负责"下一跳在哪里"。
3.1 核心跳转逻辑
当数据包跨越多个路由器进行传输时:
-
源 IP 与 目的 IP :在整个传输过程中始终不变(除非经过 NAT)。它们指明了数据的起点和终点。
-
源 MAC 与 目的 MAC :在每一跳(每一个网段)都会发生变化。
-
数据到达路由器后,路由器会进行解包(剥掉链路层报头)。
-
路由器查看 IP 报头,根据路由表决定下一跳的方向。
-
路由器重新进行封装,此时:源 MAC 变成该路由器出口的 MAC,目的 MAC 变成下一跳设备的入口 MAC。
-
结论:任何计算机问题都能通过添加一层软件层来解决。IP 层的加入,完美解决了局域网之间的隔阂。
3.2 IP地址的意义

3.3 对比IP地址和Mac地址的区别
- IP地址在整个路由过程中,一直不变(目前,我们只能这样说明,后面在修正)
- Mac地址一直在变
- 目的IP是一种长远目标,Mac是下一阶段目标,目的IP是路径选择的重要依据,mac地址是局域网转发的重要依据
3.4 IP网络的意义和网络通信的宏观流程

- IP网络层存在的意义:提供网络虚拟层,让世界的所有网络都是IP网络,屏蔽最底层网络的差异。
4 ~> Socket(插座) 编程的"入场券"
在写代码之前,必须搞清楚传输层的这两大规则。
4.1 端口号(Port)
4.1.1 端口号范围划分
-
0~1023:知名端口号,HTTP、FTP、SSH等这些广为使用的应用层协议,他们的端口号都是固定的。 -
1024~65535:操作系统动态分配的端口号.客户端程序的端口号,就是由操作系统从这个范围分配的。
4.1.2 细节

如下图:

-
知名端口(Well-known Ports):0 到 1023。这些是系统预留给标准服务的(如 80 是 HTTP,22 是 SSH)。我们自己练手时,建议使用 1024 以上的端口。
-
独立空间:同一个端口号,可以同时被一个 TCP 进程和一个 UDP 进程占用。
-
唯一性 :我们要的是"从端口到进程"的唯一性映射。内核通过哈希表(Established Table, Bind Hash Table)来快速查找报文对应的
struct sock(进一步指向task_struct)。
4.2 理解"端口号"和"进程ID"
我们之前在学习系统编程的时候,学习了pid表示唯一一个进程;此处我们的端口号也是唯一表示一个
进程,那么这两者之间是怎样的关系?
4.2.1 不是所有的进程都要进行网络通信!
进程就直接查进程PID,用进程PID在网络中标识进程唯一性,在技术角度能够一定做到!
要不要这么做?不要!
1、PID这个东西是系统指定的,用户没有办法主动设置,将来服务器端口号是要被客户端知道的,这个端口号往往需要用户主动设置,这是第一个理由,不重要;
2、PID属于系统概念,端口号是网络概念,万一PID这个系统部分发生变化,网络部分也要改,耦合性太高了,搞一个网络自己的概念------端口号,这样就解耦合了,解耦合才是最重要的------为啥不直接用PID的最本质原因!
不是所有的进程都要进行网络通信!
端口号的出现使得进程可以自主选择是否进行网络通信!
4.2.2 10086例子
打电话投诉中国电信的接待员,10086是中国移动的电话号码,员工的工号1234,10086+1234就能够锁定这个员工进行投诉了。
进程代表的是人,网络通信的本质也属于进程间通信的范畴------进程间通信的本质是让不同的进程看到同一份资源,今天这份公共资源指的就是网络,需要IP地址找主机,所以System V已经被淘汰了------主机内通信,现在已经可以跨网络通信了也可以主机内通信------扩展性很好!
一个端口号只能被一个进程占用,一个进程可以用多个端口号嘛?不行!一个端口号只能被一个进程进行占用(正确的),一个进程可以绑定1个或者N个端口号(一个进程可以绑定多个端口号,通过这些端口号发送的数据都是发给同一个进程的)。
另外,一个进程可以绑定多个端口号;但是一个端口号不能被多个进程绑定。
- 进程
PID属于系统概念,技术上也具有唯一性,确实可以用来标识唯一的一个进程,但是这样
做,会让系统进程管理和网络强耦合,实际设计的时候,并没有选择这样做。
4.3 理解源端口号和目的端口号
传输层协议(TCP和UDP)的数据段中有两个端口号,分别叫做源端口号和目的端口号.就是在描述"数
据是谁发的,要发给谁"。
4.4 理解源IP地址和目的IP地址
IP在网络中,用来标识主机的唯一性
- 注意 :后面我们会讲IP的分类,后面会详细阐述
IP的特点
但是这里要思考一个问题:数据传输到主机是目的吗?不是的。因为数据是给人用的。比如:聊天是
人在聊天,下载是人在下载,浏览网页是人在浏览?
但是人是怎么看到聊天信息的呢?怎么执行下载任务呢?怎么浏览网页信息呢?通过启动的qq,迅
雷,浏览器。
而启动的qq,迅雷,浏览器都是进程。换句话说,进程是人在系统中的代表,只要把数据给进程,人
就相当于就拿到了数据。
所以:数据传输到主机不是目的,而是手段。到达主机内部,在交给主机内的进程,才是目的。
但是系统中,同时会存在非常多的进程,当数据到达目标主机之后,怎么转发给目标进程?这就要在
网络的背景下,在系统中,标识主机的唯一性。

4.5 理解Socket

4.6 字节序(Endianness)的硬标准
-
痛点:大端机(高位存低地址)和小端机(低位存低地址)读取 4 字节整数的顺序是反的。
-
标准 :TCP/IP 协议栈强制规定,网络字节序必须是大端字节序。
-
实战函数
-
htons(Host to Network Short):处理端口号。 -
htonl(Host to Network Long):处理 IP 地址。 -
ntohs/ntohl:接收数据时转回主机序。
-
5 ~> 总结
通过这篇深度复盘,我们建立了一个完整的视图:
-
通信是进程间的博弈。
-
封装是各司其职的协议实现。
-
IP/MAC配合是跨越千山万水的保证(记住:IP 不变,MAC 一直变)。 -
字节序是跨越硬件差异的语言统一。
理论已经扎实,下一篇我们将进入代码实战,去拆解那个承载了所有协议信息的关键结构体 ------ sockaddr。
结尾
uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ### 艾莉丝努力练剑 C/C++ & Linux 底层探索者 | 一个正在努力练剑的技术博主 *** ** * ** *** 👀 【关注】 跟随我一起深耕技术领域,见证每一次成长。 ❤️ 【点赞】 让优质内容被更多人看见,让知识传递更有力量。 ⭐ 【收藏】 把核心知识点存好,在需要时随时查、随时用。 💬 【评论】 分享你的经验或疑问,评论区一起交流避坑! 不要忘记给博主"一键四连"哦! "今日练剑达成!"
"技术之路难免有困惑,但同行的人会让前进更有方向。" |
结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主"一键四连"哦!
往期回顾:
【Linux网络】计算机网络入门:协议不是玄学,从结构体到快递单,彻底搞懂网络封装与通信
🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡 ૮₍ ˶ ˊ ᴥ ˋ˶₎ა
