Linux网络编程1(OSI模型与TCP/IP协议栈)

一、网络分层模型基础

1.1 OSI七层模型

OSI(Open Systems Interconnection)模型是开放式系统互联参考模型,定义了网络通信的七层架构,自上而下分别为:
(1)应用层 :为网络用户提供具体应用服务,例如电子邮件、文件传输、网页访问等。
(2)表示层 :为不同主机间的通信提供统一的数据表示形式,解决数据编码、格式转换、加密解密等问题。
(3)会话层 :负责信息传输的组织和协调,管理进程间的会话建立、维护与终止。
(4)传输层 :管理网络通信两端的数据传输,根据需求提供可靠(如TCP)或不可靠(如UDP)的传输服务。
(5)网络层 :负责数据传输的路由选择和网际互连,通过IP地址定位目标主机。
(6)数据链路层 :负责物理相邻(通过网络介质直接相连)的主机间的数据传输,核心作用包括物理地址(MAC地址)寻址、数据帧封装、差错控制等。该层可分为逻辑链路控制子层(LLC)和介质访问控制子层(MAC)。
(7)物理层:负责将主机中的数据转换成电信号/光信号,通过网络介质(双绞线、光纤、无线信道等)传输。该层定义了通信设备的机械特性(如接口形状)、电气特性(如电压范围)、功能特性(如信号含义)等。

1.2 OSI与TCP/IP模型的关系

(1)OSI模型是通用的网络通信参考模型 ,描述了各类网络的通用架构;互联网模型是具体的网络实现模型之一。

(2)TCP/IP协议栈是互联网模型的核心实现,对OSI模型进行了合并简化,将七层架构整合为四层(或五层),具体为:应用层、传输层、网络层、接口层(或数据链路层+物理层)。

二、核心协议分类与功能

2.1 应用层协议

(1)HTTP超文本传输协议 ,用于网页浏览。
(2)TFTP简单文件传输协议 ,轻量级文件传输。
(3)FTP文件传输协议 ,标准的文件上传下载协议。
(4)SNMP简单网络管理协议 ,用于网络设备的监控与管理。
(5)DNS域名系统 ,负责将域名(如www.baidu.com)解析为IP地址,实现域名到IP的映射。
(6)DHCP动态主机配置协议,自动为网络中的主机分配IP地址、子网掩码、网关等网络配置信息。

2.2 传输层协议

(1) TCP传输控制协议 ,提供可靠面向连接 的传输服务,适用于文件传输等对可靠性要求高的场景。
(2)UDP用户数据报协议 ,提供不可靠无连接的传输服务,低延迟、网络资源占用低,适用于实时音频、视频等对实时性要求高的场景。

2.3 网络层协议

(1)IP互联网协议 ,核心功能是根据IP地址查找目标主机,实现跨网络的数据转发。
(2)ICMP互联网控制消息协议 ,用于网络故障诊断(如ping命令)、错误报告等。
(3)RIP/OSPF路由协议 ,负责路由器之间的路由信息交换,构建路由表。
(4)IGMP互联网组管理协议,用于组播通信的管理。

2.4 接口层协议

(1) ARP地址解析协议 ,将IP地址转换为MAC地址,解决数据链路层寻址问题。
(2) RARP反向地址解析协议,将MAC地址转换为IP地址(较少使用)。

三、IP地址相关知识

3.1 IP地址的组成与版本

(1)IP地址 = 网络位 + 主机位 :网络位用于标识主机所在的网络,主机位用于标识网络内的具体主机。
(2)IP地址版本
IPv432 位地址,采用点分十进制 表示(如192.168.0.1),是目前主流的IP版本。
IPv6128 位地址,采用冒分十六进制表示,解决IPv4地址枯竭问题,是未来的发展方向。

3.2 网络配置实操(Linux环境)

3.2.1 永久网络配置

(1) 配置文件路径:sudo vim /etc/network/interfaces

(2) 作用:编辑该文件可设置IP地址的手动分配或自动分配,配置后永久生效。

(3) 配置生效:修改后需重启网络服务,命令为 sudo /etc/init.d/networking restart

3.2.2 临时网络配置

临时设置IP地址:ifconfig ens33 192.168.0.13/24 up(ens33为网卡名称,192.168.0.13/24为IP地址及子网掩码,重启后配置失效)。

3.2.3 网络状态查看与测试

(1)查看网络配置 :ifconfig(查看本机所有网卡的IP、MAC等信息)。
(2)测试网络连通性 :ping www.baidu.com(测试本机是否能正常访问互联网)。
(3) 查看网络连接状态:netstat -anp(查看本机所有的网络通信连接及对应的进程)。

四、网络编程核心名词解释

(1) Socket(套接字) :应用程序打开本地网络设备后获得的文件描述符,是网络通信的接口,用于后续的数据收发操作。
(2) IP+Port :唯一标识网络中的一个应用程序。IP地址用于识别主机,端口号用于识别主机上的具体应用程序。
(3) 端口号范围 :1 ~ 65535(其中1~1023为知名端口,用于系统服务)。
(4) 网络字节序 :采用大端存储 方式,是网络设备统一使用的字节序。
(5) 主机字节序 :采用小端存储 方式,目前主流CPU(Intel、AMD、ARM)均使用小端存储。

①端口 是网络通信的编号标识(如:80) ,用来区分一台主机上的不同服务。
②套接字通信端点 ,用IP+端口+协议唯一确定,是编程操作的句柄。

五、UDP协议与编程实现

5.1 UDP协议特性

(1)无连接 :通信前无需建立连接,直接发送数据。
(2)低延迟 :网络资源使用率低。
(3)不可靠传输 :不保证数据的有序到达,可能丢失。
(4)数据报特性

① 数据与数据之间有边界,接收方需按发送方的发送次数对应接收。

② 无写阻塞:发送速度过快可能导致数据丢失。

③ 有读阻塞:接收数据时若没有数据会阻塞等待。

5.2 UDP客户端/服务器模型

(1)服务端(Server) :提供服务的一端,通常只有1个。
(2)客户端(Client):使用服务的一端,可以有多个。

5.3 UDP编程函数调用步骤

(1) 服务端 :socket() → bind() → recvfrom() → close()
(2) 客户端:socket() → sendto() → close()

5.4 核心函数详解

5.4.1 socket()函数

c 复制代码
int socket(int domain, int type, int protocol);

(1)功能:向内核申请创建一个基于内存的套接字描述符。

(2)参数:
① domain :地址族。PF_INET == AF_INET(互联网程序);PF_UNIX == AF_UNIX(单机程序)。
② type :套接字类型。SOCK_STREAM(流式套接字,对应TCP);SOCK_DGRAM(用户数据报套接字,对应UDP);SOCK_RAW(原始套接字,对应IP)。
③ protocol :协议。0表示自动适配应用层协议。

(3)返回值:成功返回套接字ID;失败返回-1。

5.4.2 bind()函数

c 复制代码
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);

(1)功能:服务端调用,将套接字描述符与指定的IP地址和端口号关联,用于从该接口接收数据。

(2)参数:
① sockfd :需要绑定IP和端口的套接字ID。
② my_addr :IPv4地址结构体(struct sockaddr_in),包含地址族、端口号、IP地址。
③ addrlen :my_addr结构体的长度。

(3)返回值:成功返回0;失败返回-1。

c 复制代码
  // IPv4地址结构体
struct sockaddr_in {
    u_short sin_family;  // 地址族(AF_INET)
    u_short sin_port;    // 端口号(网络字节序)
    struct in_addr sin_addr;  // IP地址(网络字节序)
};

5.4.3 sendto()函数

c 复制代码
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

(1) 功能:UDP协议中向目标主机发送数据。

(2) 参数:
① sockfd :本地套接字ID。
② buf :存储待发送数据的内存地址。
③ len :待发送数据的长度。
④ flags :发送方式,0表示阻塞发送。
⑤ dest_addr :目标主机的地址信息结构体(必选)。
⑥ addrlen :目标地址结构体的长度。

(3) 返回值:成功返回发送的数据长度;失败返回-1。

5.4.4 recvfrom()函数

c 复制代码
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

(1)功能:UDP协议中接收对方发送的数据。

(2)参数:
① sockfd :本地套接字ID。
② buf :存储接收数据的内存地址。
③ len :待接收数据的最大长度(通常为buf的大小)。
④ flags :接收方式,0表示阻塞接收。
⑤ src_addr :可选,存储发送方地址信息的结构体;为NULL表示不关心发送方地址。
⑥ addrlen :src_addr结构体的长度指针;若src_addr为NULL,该值也为NULL。

(3) 返回值:成功返回接收的数据长度;失败返回-1。

六、TCP协议与编程实现

6.1 TCP协议特性

(1) 面向连接 :通信前需通过"三次握手"建立连接,通信结束后需通过"四次挥手"释放连接。
(2) 可靠传输 :通过应答(ACK)、超时重传、流量控制、拥塞控制等机制保证数据有序、完整到达。
(3) 流式套接字 :数据无边界,是连续的字节流;发送次数与接收次数无需对应。
(4) 全双工通信 :拥有两个独立的缓冲区(发送缓冲区、接收缓冲区),可同时进行发送和接收操作。
(5) 有写阻塞 :发送缓冲区满时会阻塞,默认缓冲区大小约64K。
(6) 连接感知 :若一方断开连接,另一方可感知到连接状态变化。
(7) 实时性弱,网络资源消耗较大。

6.2 TCP客户端/服务器模型分类

(1)CS模型(Client/Server) :客户端为专用程序,可自定义应用协议,功能较复杂,资源存储在本地。
(2) BS模型(Browser/Server) :客户端为通用浏览器,基于HTTP协议通信,功能相对简单,资源由服务器提供。
(3) P2P模型(Peer to Peer):对等网络模型,节点既是客户端也是服务器;常见于网络下载工具,下载过程中节点间可相互传输数据。

6.3 监听套接字与通信套接字

(1)监听套接字 :由socket()创建、bind()绑定、listen()监听,用于接收客户端的连接请求,不负责数据传输。
(2)通信套接字:由accept()函数返回,用于与具体的客户端进行数据传输;一个监听套接字可对应多个通信套接字(对应多个客户端)。

6.4 TCP核心问题:黏包问题

(1)说明 :TCP通信中,数据是连续的字节流,无天然边界。若发送方多次发送数据,接收方可能一次性接收多个发送方的数据,导致数据无法正常解析,这种现象称为"黏包"。
(2)解决方法:在数据中添加协议头(如固定长度的包头,标识后续数据长度),实现数据的封包与拆包。

6.5 TCP编程函数调用步骤

(1)服务端 :socket() → bind() → listen() → accept() → recv()/send() → close()
(2)客户端:socket() → connect() → send()/recv() → close()

6.6 核心函数详解(补充TCP特有函数)

6.6.1 listen()函数

c 复制代码
int listen(int sockfd, int backlog);

(1) 功能:在指定的套接字上监听客户端的连接请求。

(2) 参数:
① sockfd :监听套接字ID。
② backlog :允许处于"三次握手"状态的最大排队连接数。

(3) 返回值:成功返回0;失败返回-1。

6.6.2 accept()函数

c 复制代码
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

(1)功能:从监听队列中取出一个有效的客户端连接,创建并返回一个新的通信套接字。

(2)参数:
① sockfd :监听套接字ID。
② addr :可选,存储客户端地址信息的结构体;为NULL表示不关心客户端地址。
③ addrlen :addr结构体的长度指针;若addr为NULL,该值也为NULL。注意:需先初始化len = sizeof(struct sockaddr),再传入&len。

(3)回值:成功返回通信套接字ID(后续通信基于该ID);失败返回-1。

6.6.3 connect()函数

c 复制代码
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

(1) 功能:客户端专用函数,向目标主机发起TCP连接请求。

(2) 参数:
① sockfd :客户端套接字ID(由socket()创建)。
② addr :目标服务器的地址信息结构体。
③ addrlen :addr结构体的长度。

(3) 返回值:成功返回0(连接建立成功);失败返回-1。

6.6.4 recv()/send()函数

c 复制代码
// recv()函数:接收数据
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

// send()函数:发送数据
int send(int sockfd, const void *msg, size_t len, int flags);

(1) 功能:TCP协议中用于数据的接收和发送。

(2) 参数:
① sockfd :服务端使用accept()返回的通信套接字ID;客户端使用socket()返回的套接字ID。
② buf/msg :接收/发送数据的内存地址。
③ len :接收/发送数据的长度。
④ flags :接收/发送方式,0表示阻塞模式。

(3) 返回值:成功返回接收/发送的数据长度;失败返回-1。

七、网络协议头核心字段

7.1 IP头核心字段

(1) TTL(生存周期) :默认值64;数据每经过一个网络节点(路由器),TTL值减1;当TTL值为0时,节点放弃转发该数据,避免数据无限循环。
(2) Flag(标志位)
① D位(Don't Fragment) :是否允许分片。
② M位(More Fragment):是否为最后一片;M=0表示是最后一片,M=1表示不是最后一片。

7.2 TCP头核心字段(标志位)

(1) A(ACK) :应答位,表示确认收到数据。
(2) P(PUSH) :推送位,表示有正文数据传递,接收方需立即将数据交给应用层。
(3) R(RST) :重置位,表示强制重置连接。
(4) S(SYN) :同步位,用于"三次握手"建立连接。
(5) F(FIN):终止位,用于"四次挥手"释放连接。

7.3 其他协议头

(1)MAC头 :包含源MAC地址、目标MAC地址、类型字段(标识上层协议类型)。
(2)UDP头:包含源端口、目标端口、数据长度、校验和等字段。

相关推荐
_Orch1d2 小时前
Modbus-TCP模糊测试实战解析
网络·网络协议·tcp/ip·modbus-tcp·工控协议安全
汽车通信软件大头兵2 小时前
Autosar KeyM模块
网络·安全·汽车·uds·isolar
AC赳赳老秦2 小时前
行业数据 benchmark 对比:DeepSeek上传数据生成竞品差距分析报告
开发语言·网络·人工智能·python·matplotlib·涛思数据·deepseek
zhglhy2 小时前
ckman创建集群报错 数据校验失败: invaild ip range
服务器·网络·tcp/ip
博语小屋2 小时前
转义字符.
c语言·c++
糕......2 小时前
Java异常处理完全指南:从概念到自定义异常
java·开发语言·网络·学习
乾元2 小时前
生成对抗样本在网络安全中的工程化解读——AI 误报、误判与对抗的真实边界
运维·网络·人工智能·python·安全·web安全
仙俊红2 小时前
计算机网络知识总结01
网络·计算机网络·智能路由器
zeijiershuai2 小时前
Linux、Linux常用命令、Linux软件安装、Linux项目部署
linux·运维·服务器