十六、Linus网络编程基础
1、Linux 网络的历史发展
早期阶段(1991–1995)
- 1991年:Linus Torvalds 发布 Linux 内核的初始版本(0.01),此时内核不支持网络功能,仅是一个单机操作系统。
- 1992年:受 BSD 套接字(BSD Sockets)启发,Linux 开始集成网络子系统,目标是兼容 TCP/IP 协议栈。首个网络实现由开发者 Ross Biro 贡献,但功能有限。
- 1993年:Alan Cox 接手网络子系统开发,重构代码并逐步增加对 TCP/IP、UDP、ICMP 等协议的支持。Linux 1.0 版本(1994年)首次包含完整的网络协议栈。成熟期(1996–2000)
- 网络驱动扩展:支持更多网卡驱动(如 NE2000、3Com),并开始支持 PPP(拨号上网)和 SLIP 协议。
- 防火墙与 NAT:1999年,Netfilter 框架(包含 iptables)被引入内核 2.4,提供强大的包过滤、NAT 和连接跟踪功能。
- IPv6 支持:内核 2.2 开始实验性支持 IPv6,2.6 版本(2003年)后逐渐完善。
高性能与虚拟化(2001–2010)
- 网络虚拟化:支持 VLAN、桥接、虚拟网络设备(如 TUN/TAP),为云计算奠定基础。
- 协议优化:改进 TCP 拥塞控制算法(如 CUBIC)、多卡支持(RSS)、零拷贝技术(Zero-Copy)提升吞吐量。
- 无线网络:完善 Wi-Fi 协议栈(802.11a/b/g/n),集成 MAC80211 子系统。
现代网络技术(2011–至今)
- 软件定义网络(SDN):支持 Open vSwitch(OVS)、VXLAN 等虚拟网络技术。
- eBPF 革命:eBPF(扩展的伯克利包过滤器)允许用户态程序在内核安全执行,用于网络监控(如 XDP)、负载均衡等。
- 容器网络:随着 Docker 和 Kubernetes 的兴起,Linux 新增 CNI(容器网络接口)、Network Namespace 隔离等技术。
2、Linux 网络协议栈的分层结构
Linux 网络协议栈遵循 TCP/IP 四层模型,但在内核中实现时分为多个逻辑层次。以下是分层结构与关键组件:
用户空间接口层
- 套接字(Sockets):为应用程序提供标准接口(如
socket()
、bind()
、send()
),支持 TCP、UDP、RAW 等多种类型。 - 系统调用:如
sendto()
、recvmsg()
,负责用户态与内核态的数据交换。
协议无关层(Socket Layer)
- Socket Buffer(sk_buff):管理网络数据包在内核中的生命周期,包含元数据(如 MAC/IP 地址、协议类型)。
- 协议分发:根据数据包类型(IPv4/IPv6)调用对应的协议处理函数。
网络协议层
- 传输层:实现 TCP、UDP、ICMP 等协议。
- TCP:包含拥塞控制(CUBIC、BBR)、状态机(SYN-SENT、ESTABLISHED)、滑动窗口等。
- UDP:无连接、尽最大努力交付,适用于实时音视频。
- 网络层:处理 IP 协议(IPv4/IPv6)、路由(Routing Table)、分片与重组。
- 路由子系统:通过 FIB(Forwarding Information Base)决定数据包下一跳。
- 邻居子系统:管理 ARP(IPv4)和 ND(IPv6),解析 MAC 地址。
设备无关层(Network Device Interface)
- 网络设备抽象:统一管理物理网卡(eth0)和虚拟设备(veth、tun)。
- 流量控制(QoS):通过 tc(Traffic Control)实现带宽限制、优先级队列(如 HTB、SFQ)。
物理设备驱动层
- 网卡驱动:与硬件交互,处理 DMA、中断、数据包收发(如
netdev_ops
结构体)。 - NAPI(New API):在高负载时减少中断次数,提升吞吐量。
3、数据包处理流程示例
接收数据包:网卡通过 DMA 将数据写入内存 → 触发中断 → NAPI 轮询 → 网络驱动解析帧头 → 上传至协议栈。
协议处理:拆解以太网帧 → IP 层路由 → TCP/UDP 处理 → 传递给 Socket Buffer。
用户态交付:通过系统调用将数据从内核 Socket Buffer 复制到用户空间缓冲区。
4、TCP/IP 协议的设计原则
为解决上述问题,Vint Cerf 和 Bob Kahn 在 1974 年提出 TCP/IP 协议的核心思想,其设计哲学包括:
-
网络互联优先(Internetworking):
- 通过 IP 协议统一不同网络的寻址和路由,屏蔽底层差异,实现“网络间的网络”(Internet)。
- 采用分层架构:将网络功能划分为链路层、网络层(IP)、传输层(TCP/UDP)、应用层,各层独立演进。
- 端到端原则(End-to-End Principle):
- 将复杂功能(如可靠性、流量控制)放在终端设备(主机)而非网络中,简化核心网络设备(如路由器)的设计。
- 例:TCP 在终端实现可靠传输,IP 仅负责“尽力而为”的转发。
-
开放性标准:
- 协议规范和实现公开(RFC 文档),鼓励厂商和开发者参与,推动生态扩展。
5、TCP/IP 如何实现网络互联
1. IP 协议:统一寻址与路由
- IP 地址:为每个网络接口分配全局唯一地址(如
192.0.2.1
),实现跨网络寻址。 - 数据包分片与重组:IP 层处理不同链路 MTU(最大传输单元)的差异,确保大数据包可通过小 MTU 网络。
- 路由协议(如 RIP、OSPF、BGP):动态学习路径,选择最优跨网络传输路径。
2. TCP 与 UDP:传输层抽象
- TCP:提供可靠、有序的字节流传输,通过滑动窗口、拥塞控制(如 Tahoe、Reno 算法)适应不同网络条件。
- UDP:提供无连接的简单传输,适用于实时应用(如 VoIP、视频流)。
3. 协议栈的灵活性
- 支持多种底层网络:IP 可运行在以太网、Wi-Fi、PPP、卫星链路等任意链路层协议上。
- 可扩展性:通过新协议(如 IPv6、QUIC)适应未来需求,同时保持向后兼容
6、经典网络体系结构模型
1. OSI 七层模型(理论参考模型)
由国际标准化组织(ISO)提出,目标是统一全球网络协议标准。尽管实际中未完全采用,但其分层思想影响深远:
层级 | 功能 | 典型协议/设备 |
---|---|---|
7. 应用层 | 提供用户接口,支持具体应用(如文件传输、电子邮件) | HTTP、FTP、SMTP、DNS |
6. 表示层 | 数据格式转换(加密、压缩)、编码统一(如 ASCII 到 Unicode) | SSL/TLS、JPEG、MPEG |
5. 会话层 | 管理会话(连接建立、维护、终止),协调设备间通信 | NetBIOS、RPC |
4. 传输层 | 端到端数据传输,提供可靠性(TCP)或实时性(UDP) | TCP、UDP |
3. 网络层 | 路由寻址,跨网络传递数据包 | IP、ICMP、路由器 |
2. 数据链路层 | 相邻节点间帧传输,错误检测(CRC) | Ethernet、Wi-Fi(MAC)、交换机 |
1. 物理层 | 定义物理介质(电缆、光纤)和信号(电信号、光脉冲) | 网卡、中继器、集线器 |
核心思想:
- 分层解耦:每层仅依赖下一层服务,独立实现功能(如修改加密算法不影响传输层)。
- 协议数据单元(PDU):每层添加/剥离头部(Header)或尾部(Trailer),如传输层数据段 → 网络层数据包 → 链路层帧。
7、TCP/IP 四层模型(实际应用标准)
由互联网工程实践发展而来,简化 OSI 模型,成为互联网的实际架构:
层级 | 功能 | 典型协议 |
---|---|---|
应用层 | 整合 OSI 的应用层、表示层、会话层功能 | HTTP、DNS、MQTT、QUIC |
传输层 | 端到端通信,保证可靠性或实时性 | TCP、UDP |
网络层 | 跨网络寻址与路由 | IPv4、IPv6、ICMP、BGP |
网络接口层 | 合并 OSI 的数据链路层和物理层 | Ethernet、Wi-Fi、PPP、ARP |
与 OSI 的对比:
- 更注重实用性:例如,TCP/IP 省略了表示层和会话层,由应用层直接处理(如 TLS 加密在应用层实现)。
- 灵活性:允许底层协议多样化(如以太网、蜂窝网络均承载 IP 数据包)。
8、网络各层的协议解释
1.网络接口和物理层mac地址:48位全球唯一,网络设备的身份标识
ARP:地址解析协议,IP地址找到mac地址
RARP:mac地址--找到IP地址
PPP协议:拨号协议(GPRS/3G/4G)
2.网络层
IP地址
IP协议:Internet protocol(分为IPv4和IPv6)
ICMP:Internet控制管理协议,Ping 命令属于ICMP
IGMP:Internet分组管理协议,广播和组播
3.传输层
TCP:(Transfer Control protocol,传输控制协议)提供面向连接的,一对一的可靠传输的协议
数据无误,数据不丢失,数据无失序
适用场景
适合对传输质量要求较高,以及传输大量数据的通信
在需要可靠数据传输的场合,通常适用TCP协议
MSN/QQ等即时通讯软件的用户登录账号管理相关的功能通常采用TCP协议
UDP:(user Datagram Protocol,用户数据报协议):提供不可靠,无连接的传输协议
适用场景
发送小尺寸数据(如对DNS服务器进行IP地址查询时)
在接收数据,给出应答较困难的网络中适用UDP(如无线网络)
适合于广播/组播式通信中
MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通常采用UDP协议
流媒体,VOD,VoIP,IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输
SCTP:(Stream Control Transmission Protocol:流控制传输协议),TCP的增强版,他能实现多主机,
多链路的通信。
4.应用层
网页访问协议:HTTP/HTTPS
邮件发送接收协议:POP3(收)/SMTP(发),IMAP(可接受邮件的一部分)
FTP:文件传输协议
Telnet/ssh:远程登录
嵌入式相关
NTP:网络时钟协议
SNMP:简单网络管理协议(实现对网络涉及集中式管理)
RTP/RSTP:用于传输音视频的协议(安防监控)
9、网络预备知识
1.socket
是一个编程接口,是一个特殊的文件描述符(对他执行IO的操作函数,比如read,write,close等),并不
仅限于TCP/IP协议,面向连接TCP,无连接UDP。
socket代表网络编程的一种资源
分类
1.流式套接字(SOCK_STREAM)。唯一对应TCP提供了一个面向连接,可靠的数据传输服务,数据无差错,无重复的发送顺序接收。内射击流量控制,避免数据流淹没慢的接收方。数据被看作式字节流,无长度限制。
2.数据包套接字(SOCK_DGRAM)。唯一对应UDP提供无连接服务器,数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。
3.原始套接字(SOCK_RAW)。对应多个协议,发送穿透了传输层可以对较低层次协议如IP,ICMP直接访问。
2.IP地址
IP地址是Internet中主机的标识,Internet中的主机要与别的机器通信必须具有一个IP地址,IP地址为32为(Ipv4)或者128位(Ipv6),每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包选择路由
表示的形式:常用点分形式,如202.38.64.10,最后都会转化成一个32位的无符号整数
mobileIPV6:local IP(本地注册的IP),roma IP(漫游IP)
特殊IP地址
局域网IP: 192.XXX.XXX.XXX 10.XXX.XXX.XXX
广播IP:xxx.xxx.xxx.255 255.255.255.255(全网广播) 网络风暴
组播IP:224.xxx.xxx.xxx ~239.xxx.xxx.xxx
3.端口号
16位数字,1-65535,
为了区分一台主机接收到的数据包应该转交给哪个任务进程处理,使用端口号来区别
预留端口,1-1023(FTP:24, SSH:22, HTTP: 80 ,HTTPS :469)
保留端口:1024-5000(不建议使用)
可以使用的端口: 5000~65535
TCP端口号于UDP端口号独立
网络里的通信是由 IP地址+端口号 来决定的
4.字节序
字节序是指不同的CPU访问内存中的多字节数据时候,存在大小端的问题
如果CPU访问的是字符串,则不存在大小端问题
一般来说X86/ARM : 小端模式
power/miop:arm作为路由时,大端模式
网络传输的时候采用大端模式
字节转换函数
把给定系统所采用的字节序称为主机字节序,为了避免不同类别主机之间在数据交换时由于对于字
节序的不同而导致的差错,引入了网络字节序。
主机字节序到网络字节序
u_long htonl(u_long hostlong);
u_short htons(u_short short);
网络字节序到主机字节序
u_long ntohl(u_long hostlong);
u_short ntohs(u_short short);
IP地址的转换
inet_aton()
将strptr所指的字符串转换成32位的网络字节序二进制值
inet_addr()
功能同上,返回转换后的地址
仅适用于IPV4,出错时返回-1。
局限性:不能用于255.255.255.255的转换
inet_ntoa()将32位网络字节序二进制地址转换成点分十进制的字符串
inet_pton()
int inet_pton(int af, const char* src ,void* dst)
将IPV4/IPV6 的地址转换成binary格式
使用于IPV4/IPV6
能正确处理255.255.255.255的转换问题
参数:
1.地址协议族(AF_INET或AF_INET6)
2.src:是一个指针(填写分点形式的IP地址(主要指IPV4))
dst:转换的结果给到dst
inet_ntop(int af,const void *src,char *dst,socklen_t size)
把ipv4和ipv6的网络字节序变成本地的字符串形式的IP地址
参数
1.af:地址协议族(AF_INET或AF_INET6)
2.src:是一个指针(32)
3.dst:输出结果为32位点分形式的IP地址
4.size:长度