鸿蒙LiteOS RK2206 Socket编程实战 UDP通信+LWIP原理全解析
B站 配套视频教程【鸿蒙 LiteOS 实战 15】LwIP socket API UDP通信 客户端
前言
在鸿蒙LiteOS(以瑞芯微RK2206为例)开发中,Socket网络编程是设备联网通信的核心技能,无论是设备与服务器数据交互、MQTT传输还是UDP广播控制,都离不开标准Socket接口与LWIP轻量级网络协议栈。
本文基于RK2206官方Demo源码,从零讲解Socket基础、阻塞通信特性、UDP协议原理,同时拆解LiteOS网络组件LWIP的底层逻辑,带你彻底掌握嵌入式设备的UDP客户端开发。
本文主要目标:
一、什么是Socket?标准Socket程序怎么写?
1. Socket 核心概念
Socket(套接字) 是计算机网络中进程间通信的端点,可以理解为网络通信的"插座":两个设备想要通信,必须各自创建一个Socket,通过IP地址+端口号唯一标识,然后基于Socket完成数据的发送与接收。
简单来说:Socket = IP地址 + 端口号,它屏蔽了底层网络协议的复杂细节,为上层应用提供统一的读写接口。
2. 标准Socket程序通用框架
无论Windows、Linux还是嵌入式LiteOS,标准Socket编程流程完全一致,分为TCP和UDP两种模式,本文重点讲UDP(无连接) 模式。
UDP Socket 标准编程流程(客户端)
1. 创建Socket → socket()
2. 配置服务器地址(IP+端口)
3. 发送数据 → sendto()
4. 接收数据 → recvfrom()
5. 关闭Socket → close()
对应本文代码核心实现
// 1. 创建UDP Socket(SOCK_DGRAM表示UDP协议)
int fd = socket(AF_INET, SOCK_DGRAM, 0);
// 2. 配置服务器地址
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET; // 地址族:IPv4
server_addr.sin_addr.s_addr = inet_addr(IP);// 服务器IP
server_addr.sin_port = htons(PORT); // 服务器端口(主机字节序转网络字节序)
// 3. 发送数据
sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&server_addr, len);
// 4. 接收数据
recvfrom(fd, buf, BUFF_LEN, 0, (struct sockaddr *)&server_addr, &len);
// 5. 关闭Socket
lwip_close(fd);
关键函数说明
- AF_INET:IPv4协议;
- SOCK_DGRAM:UDP数据报协议(TCP对应SOCK_STREAM);
- 返回值:Socket文件描述符(负数表示创建失败)。
二、什么是阻塞通信?如何从日志观察阻塞?
1. 阻塞通信定义
阻塞通信:当程序调用阻塞函数时,内核会挂起当前线程,直到函数执行完成(收到数据/超时/出错)才会继续执行后续代码。
简单理解:线程会"卡住"等待,不完成不往下走。
本文UDP代码中,recvfrom()就是典型的阻塞函数:
- 当服务器没有发送数据时,线程会停在recvfrom()这一行,一直等待数据到来;
- 只有收到数据、函数返回后,才会执行后续的LOS_Msleep(1000)。
2. 阻塞通信的特点
3. 如何从日志观察阻塞?
结合本文代码,通过串口日志可以清晰看到阻塞行为:
# 正常收发日志(无阻塞等待)
[Send] RK2206 UDP Client msg: 1
[Recv] Server reply: hello
[Send] RK2206 UDP Client msg: 2
[Recv] Server reply: hello
# 服务器未回复时(阻塞现象)
[Send] RK2206 UDP Client msg: 3
# 这里会停顿!线程阻塞在recvfrom(),无任何日志输出
# 直到服务器发送数据,才会打印[Recv]
观察关键点:
- 发送完数据后,长时间没有接收日志 → 线程阻塞在recvfrom();
- 一旦服务器回复,立即打印接收日志 → 阻塞解除,线程恢复执行。
扩展:非阻塞通信
如果不想让线程卡住,可以将Socket设置为非阻塞模式:
// 获取Socket当前状态
int flags = fcntl(fd, F_GETFL, 0);
// 设置为非阻塞
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
非阻塞模式下,recvfrom()无数据时会立即返回-1,不会挂起线程。
三、UDP协议通信原理与实战(基于本文代码)
1. UDP 协议核心原理
UDP(User Datagram Protocol,用户数据报协议) 是无连接、不可靠、轻量级的传输层协议,核心特点:
2. UDP 与 TCP 核心区别
| 连接性 | 无连接 | 面向连接(三次握手) |
| 可靠性 | 不可靠 | 可靠(重传、确认) |
| 传输效率 | 高 | 低 |
| 适用场景 | 实时通信、广播、组播 | 文件传输、可靠通信 |
3. 本文UDP客户端实战解析
本文代码是标准的LiteOS UDP客户端,完整实现了「WiFi联网→UDP循环收发」功能,核心逻辑拆解:
(1)等待WiFi联网(前置条件)
// 循环等待WiFi连接成功+获取到IP地址
while (udp_get_wifi_info(&g_wifiinfo) != 0)
{
LOS_Msleep(1000);
}
- 嵌入式设备必须先联网(获取IP),才能进行Socket通信;
- GetLinkedInfo()是RK2206 WiFi驱动接口,获取连接状态和IP。
(2)UDP循环收发
while (1)
{
// 1. 发送数据到服务器
sprintf(buf, "RK2206 UDP Client msg: %d \\r\\n", cnt++);
sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&server_addr, len);
// 2. 阻塞等待服务器回复
count = recvfrom(fd, buf, BUFF_LEN, 0, (struct sockaddr *)&server_addr, &len);
LOS_Msleep(1000);
}
- 每秒发送一条自定义消息到指定服务器;
- 阻塞等待服务器回复,收到后打印数据;
- 全程无连接,断电、断网重连后可直接恢复通信。
(3)测试方法
修改代码中3个核心参数:
#define OC_SERVER_IP "192.168.111.61" // 电脑端服务器IP
#define SERVER_PORT 20108 // 服务器端口
#define CLIENT_LOCAL_PORT 8888 // 本地端口
电脑打开网络调试助手,创建UDP服务器;
烧录程序到RK2206,WiFi联网后即可看到双向通信日志。

四、LiteOS网络组件从哪里来?LWIP协议栈全解析
1. 为什么嵌入式要用LWIP?
PC端的网络协议栈庞大复杂,占用大量内存,嵌入式设备(MCU、IoT芯片)资源有限,无法直接使用。
因此嵌入式领域通用LWIP(Light Weight IP) 轻量级网络协议栈:
- 开源、免费、体积小;
- 支持TCP/UDP/IP/ARP等完整网络协议;
- 内存占用极低,适合单片机、IoT设备;
- 鸿蒙LiteOS、FreeRTOS、RT-Thread全部内置LWIP。
2. 本文代码中的LWIP
代码开头的头文件,全部来自LWIP协议栈:
#include "lwip/udp.h"
#include "lwip/ip_addr.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/stats.h"
#include "lwip/inet_chksum.h"
我们调用的socket()/sendto()/recvfrom(),本质是LWIP对外封装的标准POSIX接口,底层由LWIP实现网络数据的打包、发送、解析。
3. LWIP在LiteOS中的架构
应用层 → 标准Socket接口(sendto/recvfrom)
↓
LWIP协议栈 → 处理TCP/UDP/IP协议
↓
网卡驱动 → WiFi/以太网硬件驱动
↓
硬件层 → RK2206 WiFi模块
4. LiteOS中LWIP的核心作用
简单说:LWIP就是LiteOS的"网络心脏",没有它,嵌入式设备无法实现TCP/IP通信。
五、完整代码说明
本文提供的代码是RK2206鸿蒙LiteOS UDP客户端完整可运行代码,仅需修改3个参数即可直接使用:
代码特性:
- 开机自动启动(APP_FEATURE_INIT);
- 自动等待WiFi联网成功;
- 阻塞式UDP循环收发,1秒发送一次;
- 串口打印收发日志,方便调试。
六、总结
本文基于RK2206实战Demo,从基础到原理全覆盖,适合鸿蒙LiteOS、嵌入式网络编程新手学习,替换IP和端口即可直接用于项目开发。



![[特殊字符] Python 网络编程从入门到精通:Socket、并发、异步与实战-171主机测评](https://www.171host.com/wp-content/uploads/2026/08/20260813095255-6a7d93f766683-220x150.png)



