当前位置: 首页 > news >正文

OSI 模型到 UDP 套接字

一、网络分层模型:OSI 与 TCP/IP 的关系

1. OSI 七层模型(理论基石)

OSI(开放系统互连)模型是描述网络通信的通用框架,将网络功能划分为 7 层,每层各司其职:

层级核心功能
应用层为用户提供网络服务(邮件、文件传输、网页访问等)
表示层统一数据表示形式(编码、加密、格式转换)
会话层管理进程间会话(建立、维护、终止通信连接)
传输层管理端到端数据传输(提供可靠 / 不可靠传输服务)
网络层负责路由选择与网际互连(IP 地址寻址、跨网络数据转发)
数据链路层相邻主机间数据传输(MAC 地址寻址、数据帧封装、差错控制,含 LLC/MAC 子层)
物理层把数据转为电信号传输(定义机械、电气特性,如双绞线、光纤、无线信道)

2. TCP/IP 协议栈(实际应用)

OSI 是理论模型,而 TCP/IP 是互联网的实际协议体系,它将 OSI 七层合并为四层(也有五层划分),是我们实际开发中接触的核心:

TCP/IP 层级对应 OSI 层级核心协议
应用层应用层 + 表示层 + 会话层HTTP(网页)、FTP/TFTP(文件传输)、DNS(域名解析)、SNMP(网络管理)、DHCP(动态 IP 分配)
传输层传输层TCP(可靠传输,如文件传输)、UDP(无连接,低延迟,如音视频)
网络层网络层IP(主机寻址)、ICMP(ping 测试)、RIP/OSPF(路由协议)、IGMP(组播)
接口层数据链路层 + 物理层ARP(IP 转 MAC)、RARP(MAC 转 IP)

二、网络编程核心基础概念

1. IP 地址与端口

  • IP 地址:由「网络位 + 主机位」组成,用于标识网络中的主机,主流为 IPv4(32 位),IPv6 为未来方向。
  • 端口号:标识主机上的应用程序,范围 1-65535(1-1023 为系统保留端口)。
  • IP + 端口:唯一标识网络中的一个应用程序(如192.168.0.112:50000)。

2. 字节序

  • 主机字节序:主流 CPU(Intel/AMD/ARM)为小端存储(低字节存低地址)。
  • 网络字节序:统一为大端存储(低字节存高地址),网络设备通信必须使用网络字节序(如htons/ntohs函数转换端口,inet_addr转换 IP)。

3. 网络配置(Linux)

  • 永久配置 IP:编辑/etc/network/interfaces,修改后执行sudo /etc/init.d/networking restart生效。
  • 临时配置 IP:ifconfig ens33 192.168.0.13/24 up(重启后失效)。
  • 常用调试命令:
    • ifconfig:查看本机网络配置(IP、网卡信息)。
    • ping www.baidu.com:测试网络连通性。
    • netstat -anp:查看本机所有网络连接(进程、端口、协议)。

4. 套接字(Socket)

Socket 是「打开网络设备后获得的文件描述符」,是网络编程的入口 —— 通过 Socket,我们可以像操作文件一样进行网络数据的收发。

三、UDP 套接字编程(核心实战)

UDP(用户数据报协议)是无连接、低延迟的传输层协议,适合音视频、实时通信等场景,核心特性:

  1. 数据报有边界,发送 / 接收次数需对应;
  2. 无写阻塞(发送过快易丢包),读操作默认阻塞;
  3. 无连接、资源占用低、延迟低。

1. UDP 编程核心流程

服务端(提供服务)客户端(使用服务)
socket()→ 创建套接字socket()→ 创建套接字
bind()→ 绑定 IP + 端口无需绑定(系统自动分配端口)
recvfrom()→ 接收客户端数据sendto()→ 发送数据到服务端
sendto()→ (可选)回显数据recvfrom()→ (可选)接收响应
close()→ 关闭套接字close()→ 关闭套接字

2. 核心函数详解

(1)创建套接字:socket ()

c

运行

int socket(int domain, int type, int protocol);
  • 参数
    • domain:地址族(AF_INET= 互联网协议,AF_UNIX= 单机通信);
    • type:套接字类型(SOCK_DGRAM=UDP,SOCK_STREAM=TCP);
    • protocol:协议(0 = 自动适配);
  • 返回值:成功返回套接字描述符,失败返回 - 1。
(2)绑定地址:bind ()

c

运行

int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
  • 参数
    • sockfd:套接字描述符;
    • my_addr:地址结构体(IPv4 用struct sockaddr_in);
    • addrlen:地址结构体长度;
  • 返回值:成功返回 0,失败返回 - 1。

IPv4 地址结构体:

c

运行

struct sockaddr_in { u_short sin_family; // 地址族(AF_INET) u_short sin_port; // 端口(网络字节序) struct in_addr sin_addr; // IP地址(网络字节序) };
(3)发送数据:sendto ()

c

运行

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
  • 参数
    • buf:待发送数据缓冲区;
    • len:发送数据长度;
    • flags:0 = 阻塞发送;
    • dest_addr:目标主机地址结构体;
  • 返回值:成功返回发送的字节数,失败返回 - 1。
(4)接收数据:recvfrom ()

c

运行

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
  • 参数
    • buf:接收数据缓冲区;
    • len:缓冲区大小;
    • src_addr:(可选)发送方地址结构体(NULL 表示不关心);
  • 返回值:成功返回接收的字节数,失败返回 - 1。

3. 实战示例(UDP 服务端 + 客户端)

(1)UDP 服务端(绑定端口接收数据并保存文件)

c

运行

#include <arpa/inet.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> #include <fcntl.h> typedef struct sockaddr* SA; #define SAVE_FILE "/home/linux/received.png" int main() { int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (-1 == sockfd) { perror("socket"); return 1; } struct sockaddr_in ser, cli; bzero(&ser, sizeof(ser)); ser.sin_family = AF_INET; ser.sin_port = htons(50000); ser.sin_addr.s_addr = inet_addr("192.168.0.112"); if (-1 == bind(sockfd, (SA)&ser, sizeof(ser))) { perror("bind"); close(sockfd); return 1; } int fp = open(SAVE_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (-1 == fp) { perror("open"); close(sockfd); return 1; } socklen_t len = sizeof(cli); printf("UDP服务端启动,端口50000等待接收...\n"); while (1) { char buf[512] = {0}; ssize_t recv_len = recvfrom(sockfd, buf, sizeof(buf), 0, (SA)&cli, &len); if (recv_len <= 0) { perror("recvfrom"); break; } printf("接收客户端(%s:%d)数据:%ld字节\n", inet_ntoa(cli.sin_addr), ntohs(cli.sin_port), recv_len); write(fp, buf, recv_len); const char *resp = "OK"; sendto(sockfd, resp, strlen(resp)+1, 0, (SA)&cli, len); bzero(buf, sizeof(buf)); } close(fp); close(sockfd); return 0; }
(2)UDP 客户端(发送二进制文件到服务端)

c

运行

#include <arpa/inet.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> #include <fcntl.h> typedef struct sockaddr* SA; int main() { int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (-1 == sockfd) { perror("socket"); return 1; } struct sockaddr_in ser; bzero(&ser, sizeof(ser)); ser.sin_family = AF_INET; ser.sin_port = htons(50000); ser.sin_addr.s_addr = inet_addr("192.168.0.112"); int fp = open("/home/linux/1.png", O_RDONLY); if (-1 == fp) { perror("open"); close(sockfd); return 1; } char buf[512] = {0}; while (1) { int ret = read(fp, buf, sizeof(buf)-1); if (ret <= 0) break; sendto(sockfd, buf, ret, 0, (SA)&ser, sizeof(ser)); bzero(buf, sizeof(buf)); int recv_len = recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL); if (recv_len > 0) printf("服务端响应:%s\n", buf); bzero(buf, sizeof(buf)); } close(fp); close(sockfd); return 0; }

四、总结

  1. 网络编程的核心是理解分层模型:OSI 是理论,TCP/IP 是实际应用,重点掌握应用层 / 传输层 / 网络层的核心协议;
  2. UDP 适合低延迟、实时性要求高的场景,核心是「无连接、数据报有边界、收发次数对应」;
  3. 套接字编程的关键:正确转换字节序、绑定地址(服务端)、用实际字节数收发数据(尤其二进制文件)。
http://www.jsqmd.com/news/131437/

相关文章:

  • 数字信号处理篇---卷积与相乘
  • 待办事项智能提醒:确保任务按时完成
  • 点击劫持防御:X-Frame-Options设置
  • 17.过保护读内存(通过内核(驱动)把应用数据复制到内核内存空间,然后返回给我们的3环程序实现)-Windows驱动
  • 使用SPICE仿真分析同或门电气特性项目应用
  • 14、数据文件与注册表分析实用指南
  • 通信原理篇---调频与调相
  • Realtek高清晰音频驱动配置详解:从零开始操作
  • 元宇宙空间交互:虚拟世界中的知识服务
  • 15、Windows 7注册表分析:USB设备追踪指南
  • SpringBoot+Vue Sringboot+个人驾校预约管理系统管理平台源码【适合毕设/课设/学习】Java+MySQL
  • 浏览器插件开发:网页内容即时解读
  • cmake安装debug版本的netgen教程
  • Altium Designer四层板PCB绘制堆叠设计完整示例
  • 留存率提升策略:让用户爱上你的产品
  • BGP 综合实验
  • SLA服务水平协议:对外承诺的质量标准
  • 高速信号PCB设计:Altium Designer 层堆栈管理器详细配置超详细版
  • RISC-V异构计算架构设计:CPU+加速器协同工作机制
  • 机器学习——Random Forest随机森林:b站up主 五分钟机器学习+time星君
  • 数据生命周期管理:从创建到销毁全过程控制
  • 节日活动安排通知:企业文化传播新渠道
  • 禁用64位系统32位文件重定向(C++代码)
  • SRI子资源完整性:确保静态资源未被篡改
  • electron-builder无法打包node_module内容的问题,以及打包各种路径报错问题
  • 35、WPF 自定义控件与绘图指南
  • 3.端口隔离——隔离模式对比
  • 内部竞聘岗位匹配:AI推荐最适合人选
  • 【2025最新】基于SpringBoot+Vue的高校就业招聘系统管理系统源码+MyBatis+MySQL
  • 36、使用WPF创建图形控件的详细指南