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

文章目录
- 前言
- [1 ~> 通信的本质 ------ 跨越主机的"进程对话"](#1 ~> 通信的本质 —— 跨越主机的“进程对话”)
- [2 ~> 传输层的抉择------TCP 与 UDP 的性格标签](#2 ~> 传输层的抉择——TCP 与 UDP 的性格标签)
-
- [2.1 UDP (用户数据报协议):](#2.1 UDP (用户数据报协议):)
- [2.2 TCP (传输控制协议):](#2.2 TCP (传输控制协议):)
- [2.3 思维导图](#2.3 思维导图)
- [3 ~> 网络字节序:关于"共识"](#3 ~> 网络字节序:关于“共识”)
-
- [3.1 总结大小端字节序问题](#3.1 总结大小端字节序问题)
-
- [3.1.1 什么是大小端字节序问题](#3.1.1 什么是大小端字节序问题)
- 3.1.2**系统级解决方案**
- [3.2 为什么不能在报文中带上端标?](#3.2 为什么不能在报文中带上端标?)
- [3.3 核心价值:建立共识](#3.3 核心价值:建立共识)
- [3.4 为什么选择大端?(大端的微弱优势)](#3.4 为什么选择大端?(大端的微弱优势))
- [4 ~> socket常见API](#4 ~> socket常见API)
- [5 ~> sockaddr 接口的"多态"实现](#5 ~> sockaddr 接口的“多态”实现)
-
- [5.1 sockaddr 结构](#5.1 sockaddr 结构)
- [5.2 结构体家族](#5.2 结构体家族)
- [5.3 万能基类](#5.3 万能基类)
- [6 ~> 为什么要有 Socket?](#6 ~> 为什么要有 Socket?)
- 结尾

前言
在网络通信中,底层细节往往决定了系统的稳定性。今天我们深入探讨三个核心问题:为什么网络字节序一定是大端?Socket 地址结构为什么要强制转换?以及 UDP 核心传输函数的逻辑。
1 ~> 通信的本质 ------ 跨越主机的"进程对话"
在网络编程中,我们必须建立一个核心认知:通信的主体不是主机,而是进程。
唯一性标识:
- IP地址定位全球唯一的主机。
-
Port(端口号) 定位主机内部唯一的网络进程。
-
公式 :
IP + Port = 全网唯一的通信进程。
设计解构:为什么不用 PID 代替 Port?
-
解耦: 进程管理(PID)是系统内核的活,网络通信(Port)是应用层与传输层的约定。如果网络层强依赖 PID,一旦进程重启 PID 变化,整个网络协议栈都会崩溃。
-
按需分配: 并非所有进程都需要网络通信,只有分配了 Port 的进程才具备"网络身份"。
2 ~> 传输层的抉择------TCP 与 UDP 的性格标签
编写 Socket 程序的第一步,就是选择合适的传输层协议。这决定了你代码的"基调"。
2.1 UDP (用户数据报协议):
- 特性: 无连接、不可靠、面向数据报。
-
比喻: 就像写信。写好地址塞进邮箱,至于信丢没丢、对方收没收到,协议本身不关心。
-
优势: 效率极高,没有握手开销。
2.2 TCP (传输控制协议):
-
特性: 有连接、可靠传输、面向字节流。
-
比喻: 就像打电话。必须先接通(三次握手),通话过程中如果有杂音或断线,双方都能立刻感知。
-
优势: 自动处理丢包、重传和排序,保障数据完整。
2.3 思维导图

3 ~> 网络字节序:关于"共识"
3.1 总结大小端字节序问题
3.1.1 什么是大小端字节序问题
不同硬件架构(如 x86 和 ARM)对多字节数据的存储方式存在分歧,这被称为 "大小端"问题。
-
大端 (Big-Endian): 高位存低地址(符合人类直觉)。
-
小端 (Little-Endian): 低位存低地址(符合机器加法逻辑)。
-
网络标准 : TCP/IP 协议族规定,网络数据流一律采用大端序。
3.1.2系统级解决方案
为了让同一套代码在不同机器上跑通,我们必须使用系统转换函数:
-
htons(Host to Network Short):将本地 16 位整数转为网络序。 -
ntohs(Network to Host Short):从网络读回数据时转为本地序。 -
逻辑提示 : 哪怕你的机器本身就是大端序,也应该调用这些函数,这叫代码的可移植性。
3.2 为什么不能在报文中带上端标?
有人提议:在数据包里带上一个标志位,告诉对方我是大端还是小端。
-
结论:这种做法很"挫",为什么"挫"?因为会造成带宽浪费。
- 带宽浪费:每一帧数据都要多带标志位,累积起来开销巨大。
-
逻辑冗余:接收方每次都要先判断、再转换,增加了协议解析的复杂度。
3.3 核心价值:建立共识
网络协议的本质就是强制性约束。凡是接入网络的设备,必须遵守统一的规矩。
-
规则 :单字节不影响,多字节(short, int 等)发送前必须统一转换为大端(Big-Endian)。
-
不服从者:如果不按大端发送,网络层虽然能传,但应用层解析出来的全是乱码。这叫"不听网络言,接入必玩完"。
3.4 为什么选择大端?(大端的微弱优势)
网络选择大端而非小端,主要基于人类阅读习惯:
-
发送逻辑:内存中低地址的数据先发,高地址的后发。
-
大端表现:在大端模式下,数据的高位存储在低地址。
-
结果 :当你使用 Wireshark 抓包时,抓到的字节流顺序与我们平时书写十六进制的顺序(如
0x1234)完全一致。这种可读性上的微弱优势,最终让大端成为了网络字节序的终极标准。
4 ~> socket常见API
cpp
// 创建 socket ⽂件描述符 (TCP/UDP, 客⼾端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端⼝号 (TCP/UDP, 服务器
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
// 开始监听socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address, socklen_t* address_len);
// 建⽴连接 (TCP, 客⼾端)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

5 ~> sockaddr 接口的"多态"实现
系统需要同时支持"网络通信"和"本地通信",但不想设计两套不同的接口。

5.1 sockaddr 结构
socketAPI是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及后面要介绍的UNIX DomainSocket。然而,各种网络协议的地址格式并不相同。

5.2 结构体家族
-
struct sockaddr_in:专用于 IPv4 网络通信。 -
struct sockaddr_un:专用于 Unix 域间(本地)通信。
5.3 万能基类
cpp
struct sockaddr
-
为了统一接口,所有的 Socket 函数(如
bind,connect)参数类型都是sockaddr*。 -
底层技巧 : 内核会先读取该结构体的前 16 位(地址族 sa_family),判断是
AF_INET还是AF_UNIX,然后再强制转换回具体的类型进行处理。
思考一下: 这种设计类似于 C++ 中的基类指针指向派生类对象,用 C 语言实现了优雅的"接口多态"。
6 ~> 为什么要有 Socket?
Socket 并不是一种协议,它是一个系统级抽象层。
-
向下: 它屏蔽了不同网络协议(IPv4/v6)、不同底层介质(以太网/Wi-Fi)以及不同硬件架构(大小端)的差异。
-
向上: 它为开发者提供了一套标准的"文件操作"接口。
结语: 好的网络程序,不在于调用了多少 API,而在于理解了每一行代码背后的协议博弈与系统抽象。
结尾
uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ### 艾莉丝努力练剑 C/C++ & Linux 底层探索者 | 一个正在努力练剑的技术博主 *** ** * ** *** 👀 【关注】 跟随我一起深耕技术领域,见证每一次成长。 ❤️ 【点赞】 让优质内容被更多人看见,让知识传递更有力量。 ⭐ 【收藏】 把核心知识点存好,在需要时随时查、随时用。 💬 【评论】 分享你的经验或疑问,评论区一起交流避坑! 不要忘记给博主"一键四连"哦! "今日练剑达成!"
"技术之路难免有困惑,但同行的人会让前进更有方向。" |
结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主"一键四连"哦!
往期回顾:
【Linux网络】计算机网络入门:协议不是玄学,从结构体到快递单,彻底搞懂网络封装与通信
🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡 ૮₍ ˶ ˊ ᴥ ˋ˶₎ა
