嵌入式解谜日志-网络编程
一、OSI 模型的核心思想
- 分层解耦:将网络通信拆解为 7 个独立层,每层仅关注自身功能(如数据封装、路由选择、流量控制),降低复杂度。
- 标准化接口:每层通过 “服务访问点(SAP)” 为上层提供服务,同时通过 “协议” 与对等层(另一台设备的同一层)通信,屏蔽底层实现细节。
- 数据封装与解封装:发送端从应用层到物理层,每层为数据添加 “首部(Header)” 或 “尾部(Trailer)”;接收端从物理层到应用层,逐层剥离首部,最终获取原始数据。
二、OSI 7 层模型详解(从顶层到底层)
应用层:为网络用户提供各种服务,例如电子邮件、文件传输等。
提供服务
1. 应用层(Application Layer,第 7 层)
- 核心功能:为应用程序提供网络服务接口,是用户与网络的直接交互层。
- 典型协议:HTTP(网页访问)、FTP(文件传输)、SMTP(邮件发送)、DNS(域名解析)、Telnet(远程登录)。
- 数据单位:用户数据(如网页内容、文件数据)。
- 示例:浏览器通过 HTTP 协议向服务器请求网页,邮件客户端通过 SMTP 发送邮件。
表示层:为不同主机间的通信提供统一的数据表示形式
(压缩,加密)
2. 表示层(Presentation Layer,第 6 层)
- 核心功能:处理数据的 “格式转换与加密”,确保发送端与接收端能理解数据格式。
- 主要任务:
- 数据编码 / 解码(如 ASCII、UTF-8);
- 数据压缩 / 解压缩(如 ZIP、GZIP);
- 数据加密 / 解密(如 SSL/TLS 中的加密处理)。
- 数据单位:PDU(Protocol Data Unit,协议数据单元,此处为 “表示层 PDU”)。
- 示例:发送端将文本数据从 UTF-8 转换为网络通用格式,接收端再转换回本地格式;网银登录时对密码进行加密传输。
会话层:负责信息传输的组织和协调,管理进程会话过程。
网络链接的状态信息
3. 会话层(Session Layer,第 5 层)
- 核心功能:建立、管理和终止 “会话连接”(应用程序之间的通信会话),确保通信双方的会话同步。
- 主要任务:
- 会话建立(如三次握手类似的会话初始化);
- 会话维护(如心跳检测、会话恢复);
- 会话终止(释放会话资源)。
- 数据单位:会话层 PDU。
- 示例:视频会议中建立双方的实时会话,若网络中断,尝试恢复会话而非重新建立;数据库连接中的会话管理(如 MySQL 的连接会话)。
传输层:管理网络通信两端的数据传输,提供可靠或不可靠的传输服务
udp(用户数据包),tcp(传输控制协议)。数据以什么方式传输(可靠与否)
4. 传输层(Transport Layer,第 4 层)
- 核心功能:提供 “端到端的可靠数据传输”,负责流量控制、差错控制和端口寻址(标识主机中的进程)。
- 典型协议:
- TCP(Transmission Control Protocol):面向连接、可靠的字节流传输(重传丢失数据、按序交付);(文件传输)
- UDP(User Datagram Protocol):无连接、不可靠的数据报传输(速度快,适合实时场景)。(视频和音频),网络开销小
- 数据单位:TCP 段(Segment)、UDP 数据报(Datagram)。
- 关键机制:
- 端口号(0-65535,如 80 端口对应 HTTP);
- TCP 的流量控制(滑动窗口)、差错控制(ACK 确认、重传)。
- 示例:浏览器(客户端进程,随机端口)通过 TCP 连接服务器的 80 端口,确保网页数据不丢失;视频通话通过 UDP 传输实时数据,容忍少量丢包。
网络层:负责数据传输的路由选择和网际互连。
IP地址(广域网)
5. 网络层(Network Layer,第 3 层)
- 核心功能:实现 “跨网络的路由选择”,将数据从源主机发送到目标主机(可能经过多个路由器)。
- 典型协议:IP(Internet Protocol,IPv4/IPv6)、ICMP(网络控制消息,如 ping 命令)、OSPF(路由协议)、ARP(地址解析,IP→MAC)。
- 数据单位:数据包(Packet)。
- 关键机制:
- IP 地址(标识网络中的主机,如 192.168.1.1);
- 路由选择(路由器通过路由表决定数据包的下一跳);
- 拥塞控制(避免网络过载)。
- 示例:发送端通过 IP 协议为数据添加目标 IP 地址,路由器根据 IP 地址和路由表将数据包转发到目标网络;ping 命令通过 ICMP 协议检测主机可达性。
数据链路层,负责物理相邻(通过网络介质相连)的主机间的数据传输,主要作用包括物理地址寻址、数据帧封装、差错控制等。该层可分为逻辑链路控制子层(LLC)和介质访问控制子层(MAC)
租建链路(局域网),组织01数据成位帧(一包),校验
6. 数据链路层(Data Link Layer,第 2 层)
- 核心功能:处理 “物理层的原始数据帧”,实现同一局域网内的可靠传输,负责 MAC 地址寻址、帧同步和差错检测。
- 典型协议:Ethernet(以太网)、PPP(点对点协议,如拨号上网)、ARP(底层地址解析)。
- 数据单位:帧(Frame)。
- 关键机制:
- MAC 地址(硬件地址,如 00:1A:2B:3C:4D:5E,标识网卡);
- 差错检测(如 CRC 校验,检测帧在传输中是否损坏);
- 冲突避免(以太网的 CSMA/CD 机制,避免同一局域网内数据冲突)。
- 示例:局域网内的主机通过 MAC 地址通信,路由器将 IP 数据包封装为以太网帧,通过 MAC 地址发送到下一跳设备;接收端通过 CRC 校验判断帧是否损坏,损坏则丢弃。
物理层,负责把主机中的数据转换成电信号,再通过网络介质(双绞线、光纤、无线信道等)来传输。该层描述了通信设备的机械、电气、功能等特性。
7. 物理层(Physical Layer,第 1 层)
- 核心功能:定义 “物理介质的电气特性和信号传输规则”,将数据链路层的帧转换为物理信号(如电信号、光信号)在物理介质上传输。
- 主要任务:
- 物理介质(如双绞线(短距离)、光纤(长距离)、无线电波((WiFi 2.4G和5G频段),无线局域网和 无线广域网));
- 信号类型(如数字信号、模拟信号);
- 引脚定义(如网线的 T568A/B 线序)、传输速率(如 100Mbps(双绞线)、10Gbps(光纤))。
- 数据单位:比特(Bit,0 或 1)。
- 示例:网线传输电信号,光纤传输光信号,WiFi 通过无线电波传输信号;网卡将帧转换为电信号,通过网线发送到交换机。
三,TCP/IP 模型(TCP/IP协议栈)(Transmission Control Protocol/Internet Protocol Model)是互联网的核心通信架构
一、TCP/IP 模型的分层结构(4 层划分)
TCP/IP 模型从顶层到底层分为以下 4 层,每层负责特定的通信功能,通过协议协作完成端到端的数据传输:
1. 应用层(Application Layer)
- 核心功能:为用户应用程序提供网络服务接口,直接处理用户数据。
- 包含协议:整合了 OSI 模型中应用层、表示层和会话层的功能,常见协议有:
- HTTP/HTTPS:网页访问(超文本传输协议);
- FTP:文件传输协议;
- SMTP/POP3:邮件发送与接收;
- DNS:域名解析(将域名转换为 IP 地址);
- SSH/Telnet:远程登录。
- 数据单位:用户数据(如网页内容、文件、邮件正文)。
- 示例:浏览器通过 HTTP 协议向服务器请求网页,邮件客户端通过 SMTP 发送邮件。
2. 传输层(Transport Layer)
- 核心功能:提供端到端的可靠数据传输,负责数据的分段、重组、流量控制和差错控制。
- 核心协议:
- TCP(Transmission Control Protocol):面向连接、可靠的字节流传输。通过三次握手建立连接,四次挥手断开连接,使用确认机制、重传机制和滑动窗口实现流量控制,确保数据不丢失、不重复、按序到达。适用于文件传输、网页加载等对可靠性要求高的场景。
- UDP(User Datagram Protocol):无连接、不可靠的数据报传输。无需建立连接,传输速度快,但不保证数据送达顺序和完整性。适用于视频通话、实时游戏、DNS 查询等对实时性要求高的场景。
- 数据单位:TCP 称为 “段(Segment)”,UDP 称为 “数据报(Datagram)”。
- 关键机制:通过端口号(0-65535)标识主机中的进程(如 80 端口对应 HTTP 服务,443 端口对应 HTTPS 服务)。
3. 网络层(Internet Layer)
- 核心功能:实现跨网络的路由选择,将数据从源主机发送到目标主机(可能经过多个路由器)。
- 核心协议:
- IP(Internet Protocol):为主机分配唯一的 IP 地址(如 IPv4 的 192.168.1.1,IPv6 的 2001:db8::1),定义数据包的格式和路由规则。
- ICMP(Internet Control Message Protocol):用于网络诊断和控制(如 ping 命令检测主机可达性,traceroute 追踪路由路径)。
- ARP(Address Resolution Protocol):将 IP 地址转换为物理 MAC 地址(同一局域网内通信需要)。
- 路由协议:如 OSPF、RIP,用于路由器之间交换路由信息,生成路由表。
- 数据单位:数据包(Packet)。
- 关键机制:路由器根据 IP 地址和路由表,决定数据包的下一跳转发路径。
4. 网络接口层(Network Interface Layer)
- 核心功能:处理物理层的原始数据,实现同一局域网内的帧传输,负责 MAC 地址寻址和数据链路管理。
- 包含内容:对应 OSI 模型的数据链路层和物理层,涉及:
- 数据链路层协议:如以太网(Ethernet)、PPP(点对点协议),定义帧的格式(包含 MAC 地址、校验码等)。
- 物理层规范:如网线、光纤等物理介质的电气特性,信号传输规则(如比特流转换为电信号 / 光信号)。
- 数据单位:帧(Frame)。
- 关键机制:通过 MAC 地址(硬件地址,如 00:1A:2B:3C:4D:5E)标识局域网内的设备,使用 CRC 校验检测帧传输是否损坏。
http:超文本传输协议
1.DNS(Domain Name System,域名系统)域名解析服务
服务器是互联网的核心基础设施之一,其核心作用是将人类可读的域名(如 www.baidu.com
)转换为计算机可识别的 IP 地址(如 202.108.2.147
),解决 “记域名易、记 IP 难” 的问题,同时实现域名与 IP 地址的动态映射,支撑互联网服务的灵活部署。
2.DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)
是一种运行在应用层的网络协议,主要用于自动为局域网内的设备分配 IP 地址及其他网络配置参数(如子网掩码、网关、DNS 服务器等),避免了手动配置 IP 的繁琐和地址冲突问题,是局域网中不可或缺的基础设施。
ip:互联网协议
icmp:互联网控制管理协议,网络诊断
ARP(Address Resolution Protocol)地址转换协议
是 TCP/IP 协议族中网络层的核心协议,用于将 IP 地址转换为物理 MAC 地址(Media Access Control Address),解决 “同一局域网内设备如何通过 IP 地址找到对方物理地址” 的问题,是局域网通信的基础。
RARP:将物理MAC地址转换成IP地址
OSI 模型(7 层) | TCP/IP 模型(4 层) | 核心对应关系 | 典型协议 / 功能 |
---|---|---|---|
应用层 | 应用层 | 直接对应,包含 OSI 的 3 层功能 | HTTP、FTP、DNS、SMTP |
表示层 | 应用层 | 合并到应用层 | 数据加密、格式转换(如 SSL) |
会话层 | 应用层 | 合并到应用层 | 会话管理(如 HTTP 会话) |
传输层 | 传输层 | 直接对应 | TCP、UDP |
网络层 | 网络层 | 直接对应 | IP、ICMP、OSPF |
数据链路层 | 网络接口层 | 合并物理层和数据链路层 | Ethernet、PPP、ARP |
物理层 | 网络接口层 | 合并物理层和数据链路层 | 网线、光纤、信号传输 |
IP 地址(Internet Protocol Address)是互联网中标识唯一标识设备的逻辑地址
(1)IP地址的组成:网络位+主机位
sudo vim/etc/network/interfaces 网络配置文件,配置网卡分配ip地址的方式。
(2)IP地址的分类:点分十进制 .ipv4
1. A 类地址(超大型网络)
- 核心特征:
二进制前 1 位固定为0
(前 4 位范围:0000
-0111
),网络位长度为 8 位,主机位长度为 24 位。 - 地址范围:
十进制1.0.0.0
~126.255.255.255
(注:0.0.0.0
表示本机未分配 IP,127.0.0.0
为回环地址,均不属于 A 类可用地址)。 - 子网掩码:默认
255.0.0.0
(二进制11111111.00000000.00000000.00000000
)。 - 可容纳主机数:
主机位共 24 位,理论可容纳2²⁴ - 2 = 16777214
台设备(减 2 是排除 “网络地址” 和 “广播地址”)。 - 适用场景:早期互联网主干网、超大型机构(如早期的 IBM、AT&T),目前 A 类地址已基本分配完毕。
2. B 类地址(大中型网络)
- 核心特征:
二进制前 2 位固定为10
(前 4 位范围:1000
-1011
),网络位长度为 16 位,主机位长度为 16 位。 - 地址范围:
十进制128.0.0.0
~191.255.255.255
。 - 子网掩码:默认
255.255.0.0
(二进制11111111.11111111.00000000.00000000
)。 - 可容纳主机数:
主机位共 16 位,理论可容纳2¹⁶ - 2 = 65534
台设备。 - 适用场景:中型企业、高校、运营商的二级网络(如某省电信的城域网)。
3. C 类地址(小型网络)
- 核心特征:
二进制前 3 位固定为110
(前 4 位范围:1100
-1101
),网络位长度为 24 位,主机位长度为 8 位。 - 地址范围:
十进制192.0.0.0
~223.255.255.255
。 - 子网掩码:默认
255.255.255.0
(二进制11111111.11111111.11111111.00000000
)。 - 可容纳主机数:
主机位共 8 位,理论可容纳2⁸ - 2 = 254
台设备(最适合小型局域网)。 - 私有:192.168.0.0 - 192.168.255.255
- 静态路由
192.168.0.0
192.168.0.1网关
192.168.0.255 - 适用场景:家庭 WiFi、小型办公室、商铺等设备数量较少的网络(如家庭中 10 台以内的手机、电脑、智能设备)。
4. D 类地址(组播地址)
- 核心特征:
二进制前 4 位固定为1110
(前 4 位范围:1110
),无网络位和主机位之分,不用于单播通信,仅用于 “组播”(一对多通信)。 - 地址范围:
十进制224.0.0.0
~239.255.255.255
。 - 典型用途:
视频会议(向多个参会设备同步发送视频流)、IPTV(向多个用户推送电视信号)、路由器之间的路由协议通信(如 OSPF)。 - 示例:
224.0.0.1
是 “所有主机” 的组播地址,224.0.0.2
是 “所有路由器” 的组播地址。
5. E 类地址(保留地址)
- 核心特征:
二进制前 4 位固定为1111
(前 4 位范围:1111
),无网络位和主机位之分,不对外开放使用。 - 地址范围:
十进制240.0.0.0
~255.255.255.255
(注:255.255.255.255
是全局广播地址,属于特殊用途,不归属 E 类可用地址)。 - 用途:仅用于科研、实验或未来扩展(如 IPv4 向 IPv6 过渡的技术测试),目前无实际商用场景。
1.配置网络设置:
命令:
①ifconfig:查询网络地址
ip: ifconfig ethX X.X.X.X/24 up ifconfig ens33 192.168.0.13/24 up 255.255.255.0
网关 :route add default gw x.x.x.x
DNS : vi /etc/resolv.conf ==>nameserver 8.8.8.8
测试 : ping www.baidu.com
②ping 网络诊断
③netstat -anp:查看本机所有的网络连接信息
2.网络接口:
1.socket 套接字:用于网络通信的一组接口函数。
本质:文件描述符(网络设备的)
2.ip+port:地址+端口:
ip地址用来识别主机
port端口用来识别应用程序(查找进程)
port(端口):分为TCP port/UDP port
范围:1-65535
1000以内的端口为系统使用
3.网络字节序:①pc,arm : 都是小端存储设备(数据的地位存放在低地址)
②网络:大端存储
udp,不可靠(丢包)低延迟 网络开销小,无链接
(1)server(服务端)
1.socket:创建套接字,打开网路设备
2.bind :给套接字,设置ip+port(地址+端口)
3.recvform :先阻塞等待客服端发送文件
4. sendto:送回客服端
#include<arpa/inet.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include<time.h>
typedef struct sockaddr * (SA);
int main(int argc, char **argv)
{//创建套接字sockfd//AF_INET为互联网类型网络//SOCK_DGRAM为UDP端口类型(不可靠)int sockfd=socket(AF_INET,SOCK_DGRAM,0);if(-1==sockfd){perror("socket");return 1;}//man 7 ip查看地址结构体struct sockaddr_in ser,cli;ser.sin_family=AF_INET;ser.sin_port=htons(50000);ser.sin_addr.s_addr=inet_addr("192.168.1.23");int ret=bind(sockfd,(SA)&ser,sizeof(ser));if(-1==ret){perror("bind");return 1;}time_t tm;socklen_t len=sizeof(cli);while (1){char buf[512]={0};//等待接收客户端time(&tm);recvfrom(sockfd,buf,sizeof(buf),0,(SA)&cli,&len);sprintf(buf,"%s %s",buf,ctime(&tm));//向客户端发送printf("recv %s\n",buf);sendto(sockfd,buf,strlen(buf),0,(SA)&cli,len);}//system("pause");return 0;
}
(2)client(客户端)
1.socket,打开网络设备
2. sendto:向服务端发送信息
3.recvform:接受服务端传回的信息
#include<arpa/inet.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include<time.h>
typedef struct sockaddr * (SA);
int main(int argc, char **argv)
{//创建套接字,打开网络int sockfd=socket(AF_INET,SOCK_DGRAM,0);if(-1==sockfd){perror("socket");return 1;}//struct sockaddr_in ser;ser.sin_family=AF_INET;ser.sin_port=htons(50000);ser.sin_addr.s_addr=inet_addr("192.168.1.23");int i=10;while (i--)//循环发送{char buf[512]="hello,白海英";//发送信息sendto(sockfd,buf,strlen(buf),0,(SA)&ser,sizeof(ser));//将buf清空,准备接收服务端bzero(buf,sizeof(buf));//接收服务端信息recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);printf("from ser:%s\n",buf);sleep(1);}close(sockfd);//system("pause");return 0;
}
做服务端的ip地址是自己的,
做客户端的ip地址是服务端的。
#include<arpa/inet.h> // 提供IP地址转换函数(如inet_addr)和网络数据结构
#include<stdio.h> // 标准输入输出函数(如printf、perror)
#include<stdlib.h> // 标准库函数(如exit,确保兼容性)
#include<string.h> // 字符串操作函数(如bzero,可扩展使用)
#include<sys/types.h> // 定义系统数据类型(如ssize_t、socklen_t)
#include<sys/socket.h> // 提供套接字操作函数(如socket、sendto、recvfrom)
#include<unistd.h> // 提供文件关闭函数(close)和睡眠函数(sleep)
#include <netinet/in.h> // 定义网络地址结构(如struct sockaddr_in)
#include <netinet/ip.h> // 提供IP协议相关定义(用于兼容性)
#include <fcntl.h> // 提供文件打开控制选项(如O_RDONLY、O_WRONLY)// 类型重定义:将struct sockaddr*简化为SA,减少代码冗余
typedef struct sockaddr * (SA);int main(int argc, char **argv)
{// 创建UDP套接字(打开网络通信通道)int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd){perror("socket"); // 打印套接字创建失败原因return 1;}// 初始化服务端地址结构(指定数据发送目标)struct sockaddr_in ser;ser.sin_family = AF_INET; // 使用IPv4协议ser.sin_port = htons(50000); // 服务端端口(网络字节序)ser.sin_addr.s_addr = inet_addr("192.168.1.123"); // 服务端IP地址// 打开源文件(待发送的图片)和目标文件(接收后保存的图片)int fd = open("1.png", O_RDONLY); // 只读打开源文件int fd_s = open("2.png", O_WRONLY | O_CREAT | O_TRUNC, 0666); // 创建/打开目标文件if (fd == -1 || fd_s == -1) {perror("文件打开失败"); // 打印文件操作失败原因close(fd);close(fd_s);close(sockfd);return 1;}char buf[1024]; // 数据缓冲区(每次最多处理1024字节)ssize_t n; // 存储实际读取/发送的字节数(支持负数表示错误)socklen_t ser_len = sizeof(ser); // 服务端地址结构长度/***************************************************************************** 核心循环:分块读取文件 → 发送数据 → 接收反馈 → 写入目标文件* 循环逻辑:"读一点,发一点,收一点,写一点"(而非一次性处理整个文件)* 适用场景:大文件传输(避免占用过多内存)、网络分片传输(符合UDP特性)***************************************************************************/// read函数:从源文件fd读取数据到buf,最多读sizeof(buf)=1024字节// 循环条件:n > 0 → 读取到有效数据,继续处理;n ≤ 0 → 文件读完或出错,退出循环while ((n = read(fd, buf, sizeof(buf))) > 0) {/****************** 发送阶段:将刚读取的一块数据发送给服务端 ******************/// sendto参数n:使用实际读取的字节数(而非缓冲区大小),避免发送无效空数据// 例如:文件只剩500字节时,n=500,仅发送500字节有效数据sendto(sockfd, buf, n, 0, (SA)&ser, sizeof(ser));//清空buf,为下一次循环做准备bzero(buf, sizeof(buf));/****************** 接收阶段:等待服务端回传数据(确认或原数据) ******************/// 覆盖buf中的发送数据(因发送数据已通过网络发出,缓冲区可复用)recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);/****************** 写入阶段:将服务端回传的数据写入目标文件 ******************/// 写入字节数与发送时的n一致,确保每块数据大小匹配,最终文件完整write(fd_s, buf, n);}// 释放资源(关闭所有打开的文件和套接字,避免资源泄漏)close(sockfd);close(fd);close(fd_s);return 0;
}
重点理解while循环:
核心逻辑是 while ((n = read(fd, buf, sizeof(buf))) > 0)
循环—— 它的行为是 “读一点、发一点、收一点、写一点”,即每次从文件中读取一块数据(最多 1024 字节),立即发送给服务端,再接收服务端的反馈,最后将反馈数据写入目标文件,直到文件全部读完。
循环自动执行下一次的原理
循环的核心是条件判断和数据读取的连续性:
每次循环结束后,自动回到条件判断
当循环体内的代码(发送、接收、写入)执行完毕后,程序会自动回到循环开头,重新执行n = read(fd, buf, sizeof(buf))
。read
函数会 “记住” 上一次的读取位置
操作系统会为打开的文件(fd
)维护一个 “文件指针”,记录当前读取到的位置。每次read
后,指针会自动移动到下一个未读取的字节。- 例如:第一次读取 1024 字节后,指针指向第 1025 字节;
- 下一次
read
会从第 1025 字节开始读取,直到文件末尾。
循环终止条件
当read
返回0
(文件读完)或-1
(读取错误)时,n > 0
条件不成立,循环自动退出,不会进行下一次。
while
循环的自动迭代特性和文件指针的自动移动,实现了 “读完一块数据后,自动进行下一次循环处理下一块数据”,直到整个文件传输完成。无需添加额外代码控制 “下一次循环”,循环会根据文件读取状态自动执行或终止。