基于小智派-LZ3863星闪开发板:OpenHarmony WiFi 网络开发 — TCP 客户端

📅 2026/8/1 17:09:17
基于小智派-LZ3863星闪开发板:OpenHarmony WiFi 网络开发 — TCP 客户端
1、实验简介参考网址https://gitee.com/Lockzhiner-Electronics/lz3863/tree/master/apps/c2_wifi_tcp_client1.1、实验目的本实验旨在帮助学习者掌握 OpenHarmony 轻量系统中WiFi TCP 网络通信的基本使用方法。通过本实验你将学会理解TCP 协议的面向连接、可靠传输特性及客户端/服务端通信模型在开发板上以 STA 模式连接 WiFi 热点通过 DHCP 获取 IP 地址使用 lwIPSocket API创建 TCP 套接字完成连接、发送、接收与关闭掌握 WiFi 连接与 TCP 通信的完整联调流程完成案例代码的编译、烧录与串口现象观察。1.2、实验内容本案例在 LZ3863-星闪开发板上实现TCP 客户端功能先连接指定 WiFi 热点再与 TCP 服务器建立连接发送测试数据并持续接收服务器响应全过程通过串口打印日志。项目说明源文件wifi_tcp_client_example.c主程序、wifi_connecter.cWiFi 封装WiFi 模式STA站点/客户端目标 SSIDlzdz目标密码88888888TCP 服务器 IP192.168.137.1TCP 服务器端口777发送测试数据wifi_tcp_test_date任务线程tcp_demo_task栈大小 8192 字节初始化入口APP_FEATURE_INIT(tcp_demo_entry)典型联调拓扑┌─────────────────┐ WiFi ┌─────────────────┐ │ PC / 手机热点 │ ◄──────────────────► │ LZ3863 开发板 │ │ SSID: lzdz │ │ (TCP Client) │ │ IP: 192.168. │ TCP :777 │ │ │ 137.1 │ ◄──────────────────► │ │ │ (TCP Server) │ │ │ └─────────────────┘ └─────────────────┘说明默认服务器 IP192.168.137.1为 Windows 移动热点网关地址。若使用其他路由器或开发板作为 TCP 服务器需同步修改TCP_SERVER_IP宏定义。1.3、实验环境项目说明硬件LZ3863-星闪开发板、USB 数据线软件OpenHarmony v5.1.0 源码、hb 编译工具网络环境可连接的 WiFi 热点SSID/密码与代码一致TCP 服务器PC 端网络调试工具 /nc/ Python 脚本或c3_wifi_tcp_server案例调试工具串口助手波特率 1152008N1案例路径applications/sample/wifi-iot/app/c2_wifi_tcp_client/2、基础知识2.1、TCP 协议概述TCPTransmission Control Protocol传输控制协议是一种面向连接的、可靠的传输层协议具有以下特点特性说明面向连接通信前需通过三次握手建立连接结束后四次挥手断开可靠传输通过序号、确认、重传机制保证数据不丢失、不重复全双工连接建立后双方可同时发送和接收数据字节流数据以连续字节流形式传输无固定报文边界TCP 通信采用客户端/服务端C/S模型角色职责本实验对应TCP 服务端绑定端口、监听连接、接受客户端请求PC 或另一块开发板TCP 客户端主动发起连接、发送/接收数据本案例开发板2.2、Socket 编程基础Socket套接字是网络编程的抽象接口lwIP 提供了与 BSD Socket 兼容的 API。TCP 客户端的典型流程socket() → 创建套接字 ↓ 配置 sockaddr_inIP 端口 ↓ connect() → 连接服务器三次握手 ↓ send() / recv() → 收发数据 ↓ closesocket() → 关闭连接关键数据结构sockaddr_instructsockaddr_inserver_addr{0};server_addr.sin_familyAF_INET;// IPv4server_addr.sin_porthtons(port);// 端口号转网络字节序inet_pton(AF_INET,host,server_addr.sin_addr);// IP 地址字符串 → 二进制字节序转换函数作用htons()主机字节序 → 网络字节序16 位用于端口htonl()主机字节序 → 网络字节序32 位用于 IPinet_pton()字符串 IP → 二进制网络地址inet_ntoa()二进制网络地址 → 字符串 IP2.3、WiFi STA 连接与网络层本案例在 TCP 通信之前需先通过ConnectToHotspot()完成 WiFi 连接与 IP 获取。完整流程为启用 STA 模式 → 扫描热点 → 匹配 SSID → 关联连接 → 启动 DHCP 客户端 → 获取 IP 地址 → 网络层就绪获取 IP 后开发板与 TCP 服务器处于同一局域网方可进行 Socket 通信。2.4、软件调用层次本案例的软件调用层次如下应用层wifi_tcp_client_example.c ├── tcp_demo_entry() ← APP_FEATURE_INIT 注册入口 ├── tcp_demo_task() ← 任务线程WiFi 连接 TCP 客户端 └── tcp_client_test() ← TCP 核心逻辑 │ WiFi 封装层wifi_connecter.c └── ConnectToHotspot() ← 扫描、连接、DHCP 获取 IP │ 协议栈 / 驱动层 ├── lwIP Socket APIsocket/connect/send/recv ├── lwIP 网络协议栈TCP/IP、DHCP └── WiFi 驱动HMAC/DMAC2.5、核心 API 介绍2.5.1、头文件#includecmsis_os2.h#includelwip/sockets.h#includeohos_init.h#includeosal_debug.h#includewifi_connecter.h#includeerrno.h#includestdio.h#includestring.h#includeunistd.h2.5.2、Socket APIAPI 名称功能说明socket(AF_INET, SOCK_STREAM, 0)创建 IPv4 TCP 套接字返回套接字描述符inet_pton(af, src, dst)将字符串 IP 地址转换为网络字节序二进制形式connect(sockfd, addr, addrlen)向 TCP 服务器发起连接三次握手send(sockfd, buf, len, flags)向已连接套接字发送数据返回实际发送字节数recv(sockfd, buf, len, flags)从已连接套接字接收数据返回实际接收字节数closesocket(sockfd)关闭套接字释放资源2.5.3、WiFi 与应用层 APIAPI 名称功能说明ConnectToHotspot(ssid, password)扫描并连接指定热点完成 DHCP 获取 IPDisconnectWithHotspot()停止 DHCP 并断开 WiFi 连接osThreadNew(func, arg, attr)创建 RTOS 线程osDelay(ticks)线程延时100 ticks ≈ 1 秒tick 10 msAPP_FEATURE_INIT(func)注册应用特性初始化入口系统启动后自动执行3、程序设计3.1、程序架构本案例目录结构c2_wifi_tcp_client/ ├── wifi_tcp_client_example.c # TCP 客户端主程序 ├── wifi_connecter.c # WiFi 连接封装实现 ├── wifi_connecter.h # 封装接口头文件 ├── BUILD.gn # GN 编译配置 ├── README_zh.md # 案例简要说明 └── 实验手册.md # 本实验手册程序执行流程系统启动 │ ▼ tcp_demo_entry() ← APP_FEATURE_INIT 注册自动执行 │ ▼ osThreadNew(tcp_demo_task) ← 创建 TCP 示例任务线程 │ ▼ tcp_demo_task() ├── ConnectToHotspot() ← 连接 WiFi 热点DHCP 获取 IP ├── osDelay(800) ← 等待网络稳定约 8 秒 └── tcp_client_test() ← 启动 TCP 客户端通信 ├── socket() ← 创建套接字 ├── connect() ← 连接 TCP 服务器 ├── send() ← 发送测试数据 ├── recv() 循环 ← 持续接收服务器响应 └── closesocket() ← 关闭连接3.2、源文件说明文件说明wifi_tcp_client_example.cTCP 客户端主程序包含 WiFi 连接、TCP 通信及任务线程wifi_connecter.cWiFi 封装实现ConnectToHotspot、StartHotspot、DisconnectWithHotspotwifi_connecter.h封装接口声明BUILD.gn编译配置生成wifi_tcp_client_example静态库3.3、关键代码分析1WiFi 与 TCP 配置参数#defineWIFI_SSIDlzdz#defineWIFI_PASSWORD88888888#defineTCP_SERVER_IP192.168.137.1#defineTCP_SERVER_PORT777staticcharrequest_data[50]wifi_tcp_test_date;staticcharresponse_data[100];实验前请根据实际网络环境修改上述宏定义确保 SSID、密码、服务器 IP 与端口正确。2系统入口 — tcp_demo_entry通过APP_FEATURE_INIT注册应用入口创建tcp_demo_task线程staticvoidtcp_demo_entry(void){osThreadAttr_tattr{.nametcp_demo_task,.stack_size8192,.priorityosPriorityNormal};if(osThreadNew(tcp_demo_task,NULL,attr)NULL){printf([tcp_demo_entry] Failed to create tcp_demo_task!\r\n);}}APP_FEATURE_INIT(tcp_demo_entry);3任务线程 — tcp_demo_task任务线程先完成 WiFi 连接延时等待网络稳定后再启动 TCP 客户端staticvoidtcp_demo_task(void*arg){(void)arg;printf(Starting Wi-Fi connection to SSID: %s...\r\n,WIFI_SSID);if(ConnectToHotspot(WIFI_SSID,WIFI_PASSWORD)!0){printf(Failed to connect to AP.\r\n);return;}printf(Wi-Fi connected successfully.\r\n);osDelay(800);// 等待约 8 秒确保网络栈稳定tcp_client_test(TCP_SERVER_IP,TCP_SERVER_PORT);}4TCP 客户端核心 — tcp_client_testtcp_client_test()实现完整的 TCP 客户端通信流程voidtcp_client_test(constchar*host,unsignedshortport){ssize_tret0;// 1. 创建 TCP 套接字intsockfdsocket(AF_INET,SOCK_STREAM,0);if(sockfd0){printf(Failed to create socket! errno%d\r\n,errno);return;}// 2. 配置服务器地址structsockaddr_inserver_addr{0};server_addr.sin_familyAF_INET;server_addr.sin_porthtons(port);if(inet_pton(AF_INET,host,server_addr.sin_addr)0){printf(inet_pton failed! Invalid IP address.\r\n);closesocket(sockfd);return;}// 3. 连接 TCP 服务器printf(Attempting to connect to %s:%d...\r\n,host,port);if(connect(sockfd,(structsockaddr*)server_addr,sizeof(server_addr))0){printf(connect tcp server failed! errno%d\r\n,errno);closesocket(sockfd);return;}printf(Connected to TCP server %s successfully!\r\n,host);// 4. 发送测试数据retsend(sockfd,request_data,strlen(request_data),0);if(ret0){printf(send request failed! errno%d\r\n,errno);}else{printf(Sent request{%s} %ld bytes to TCP server!\r\n,request_data,ret);}// 5. 持续接收服务器响应while(1){memset(response_data,0,sizeof(response_data));retrecv(sockfd,response_data,sizeof(response_data)-1,0);if(ret0){printf(recv_data failed or connection closed, ret%ld, errno%d\r\n,ret,errno);break;}response_data[ret]\0;printf(Received data{%s} from server!\r\n,response_data);osDelay(100);// 防止忙等待}// 6. 关闭套接字closesocket(sockfd);}5WiFi 封装层 — ConnectToHotspot 概要ConnectToHotspot()在wifi_connecter.c中实现主要步骤调用wifi_sta_enable()启用 STA 模式循环执行wifi_sta_scan()扫描get_match_network()匹配目标 SSID调用wifi_sta_connect()发起关联等待WIFI_CONNECTED状态在wlan0接口上启动 DHCP 客户端获取 IP 地址并打印。3.4、程序执行流程TCP 服务器 (PC/开发板)WiFi 热点开发板 (TCP Client)TCP 服务器 (PC/开发板)WiFi 热点开发板 (TCP Client)连接关闭或出错时 closesocket()APP_FEATURE_INIT → tcp_demo_entryosThreadNew(tcp_demo_task)ConnectToHotspot(lzdz)关联成功 DHCP 分配 IPosDelay(800) 等待网络稳定socket() connect(192.168.137.1:777)三次握手完成send(wifi_tcp_test_date)服务器响应数据recv() 循环打印接收内容4、编译步骤以下步骤只需在首次编译时完成 4.14.3 的配置注册。4.1、确认案例目录确认案例已位于 OpenHarmony 源码目录下applications/sample/wifi-iot/app/c2_wifi_tcp_client/ ├── wifi_tcp_client_example.c ├── wifi_connecter.c ├── wifi_connecter.h ├── BUILD.gn └── 实验手册.md若从外部复制请将c2_wifi_tcp_client目录放到上述app/路径下。4.2、修改 BUILD.gn注册编译组件编辑applications/sample/wifi-iot/app/BUILD.gn在features列表中添加本案例lite_component(app) { features [ startup, c2_wifi_tcp_client:wifi_tcp_client_example, // 添加此行 ] }4.3、修改 SDK 配置文件步骤 1编辑device/soc/hisilicon/ws63v100/sdk/build/config/target_config/ws63/config.py找到ws63-liteos-app配置段在其ram_component列表中添加wifi_tcp_client_example步骤 2编辑device/soc/hisilicon/ws63v100/sdk/libs_url/ws63/cmake/ohos.cmake找到ws63-liteos-app对应的set(COMPONENT_LIST部分添加wifi_tcp_client_example4.4、编译固件在 OpenHarmony 源码根目录下执行编译rm-rfout hbset-root.# 通过上下方向键选择 ws63 对应的编译分支如 nearlink_dk_3863 / ws63-liteos-apphb build-f编译成功后使用开发板配套烧录工具将固件烧写到 LZ3863-星闪开发板。4.5、修改网络参数可选烧录前若实际 WiFi 热点或 TCP 服务器地址与默认值不同请编辑wifi_tcp_client_example.c中的宏定义#defineWIFI_SSIDlzdz// 改为实际热点名称#defineWIFI_PASSWORD88888888// 改为实际热点密码#defineTCP_SERVER_IP192.168.137.1// 改为 TCP 服务器 IP#defineTCP_SERVER_PORT777// 改为 TCP 服务器端口修改后需重新编译并烧录。5、运行结果5.1、硬件与网络准备方式一PC 移动热点 PC 端 TCP 服务器推荐在 PC 上开启移动热点SSID 设为lzdz密码设为88888888确认 PC 热点网关 IP 为192.168.137.1Windows 默认若不是请修改TCP_SERVER_IP在 PC 上启动 TCP 服务器监听端口777# 方式 A使用 netcatLinux / macOSnc-l777# 方式 B使用 Pythonpython3-c import socket s socket.socket() s.bind((0.0.0.0,777))s.listen(1) print(Waiting for connection on port 777...) conn, addr s.accept() print(fConnected from {addr}) conn.send(bHello from TCP server!) while True: data conn.recv(1024) if not data: break print(fReceived: {data.decode()}) conn.close() 开发板上电或复位通过 USB 连接 PC 打开串口助手1152008N1。方式二使用 c3_wifi_tcp_server 案例联调准备可连接的 WiFi 路由器或手机热点SSID/密码与代码一致另一块开发板烧录c3_wifi_tcp_server固件作为 TCP 服务端查看服务端串口日志中打印的 IP 地址将其填入本案例的TCP_SERVER_IP宏定义后重新编译烧录客户端固件。建议先启动 TCP 服务器并确认监听成功再复位开发板以提高首次连接成功率。5.2、串口配置参数值波特率115200数据位8停止位1校验位无流控无5.3、预期串口输出烧录固件并复位后串口助手可观察到完整的 WiFi 连接与 TCP 通信过程Starting Wi-Fi connection to SSID: lzdz... Start Scan ! [WIFI_STA_SAMPLE] Scan done!. STA try connect. [WIFI_STA_SAMPLE] Connect succ!. STA DHCP start. STA DHCP bound success. STA IP 192.168.137.x Connect success. Wi-Fi connected successfully. Attempting to connect to 192.168.137.1:777... Connected to TCP server 192.168.137.1 successfully! Sent request{wifi_tcp_test_date} 18 bytes to TCP server! Received data{Hello from TCP server!} from server!其中Start Scan !/Scan done!表示 WiFi 热点扫描完成Connect succ!/STA IP 192.168.137.x表示 WiFi 关联成功并获取 IPWi-Fi connected successfully.表示应用层确认 WiFi 就绪Connected to TCP server ... successfully!表示 TCP 三次握手完成Sent request{wifi_tcp_test_date}表示测试数据发送成功Received data{...} from server!表示收到服务器响应。5.4、PC 端 TCP 服务器预期现象若使用 netcat 或 Python 脚本作为服务器PC 端可观察到Waiting for connection on port 777... Connected from (192.168.137.x, xxxxx) Received: wifi_tcp_test_date表示开发板已成功连接并发送测试数据。5.5、结果分析现象说明输出Wi-Fi connected successfully.WiFi 连接与 DHCP 获取 IP 成功输出Connected to TCP server ... successfully!TCP 连接建立成功输出Sent request{wifi_tcp_test_date}数据发送成功输出Received data{...} from server!服务器响应接收成功输出Failed to connect to AP.WiFi 连接失败检查 SSID/密码输出connect tcp server failed!TCP 连接失败检查服务器 IP/端口及防火墙输出recv_data failed or connection closed服务器主动关闭连接或网络中断5.6、常见问题排查问题可能原因解决方法反复Can not find AP热点未开启或 SSID/密码不匹配确认热点已开启宏定义与实际一致WiFi 连接成功但 TCP 连接失败服务器未启动或 IP/端口错误先启动 TCP 服务器核对TCP_SERVER_IP和端口connect tcp server failed! errno113路由不可达IP 地址错误确认开发板与服务器在同一网段connect tcp server failed! errno111服务器端口未监听检查 PC 防火墙确认端口 777 已开放PC 端收不到数据防火墙拦截关闭防火墙或添加端口 777 入站规则编译报错找不到组件BUILD.gn 或 config.py 未修改逐步核对 4.2、4.3 节的配置项仅收到一次数据后停止服务器关闭连接正常现象recv()返回 0 时客户端退出循环6、实验扩展完成基本实验后可尝试以下扩展练习修改通信内容更改request_data字符串观察 PC 端接收到的数据变化双向通信在recv()循环中增加send()回发逻辑实现简单的请求-响应交互配合 TCP 服务端案例使用c3_wifi_tcp_server案例实现两块开发板之间的 TCP 通信连接超时处理在connect()前设置套接字超时setsockoptSO_RCVTIMEO避免无限阻塞断线重连TCP 连接断开后自动重新connect()实现简单的断线重连机制改用 UDP 通信参考后续 UDP 案例对比 TCP 与 UDP 在可靠性、效率上的差异HTTP 应用在 TCP 基础上发送 HTTP GET 请求理解应用层协议与传输层的关系。