2. 网络基础回顾:TCP/IP协议栈、Socket编程基础、HTTP/HTTPS协议、MQTT协议简介
各位同学,在正式开始搞WiFi配网和LTE切换之前,咱们得先把地基打牢。说实话,我见过太多工程师在协议栈上栽跟头——配网连上了,数据发不出去;切换成功了,业务却断了。说白了,都是基础不牢。
这一节我会带着大家快速过一遍TCP/IP协议栈、Socket编程、HTTP/HTTPS和MQTT。嗯,都是干货,没有废话。
2.1 TCP/IP协议栈——物联网通信的骨架
TCP/IP协议栈,你想想看,它就是互联网世界的交通规则。从你手机上的App,到云端的服务器,数据要经过四层才能到达对端。
| 层级 | 名称 | 核心协议/作用 | 我常关注的要点 |
|---|---|---|---|
| 第4层 | 应用层 | HTTP、MQTT、CoAP、WebSocket | 数据格式、会话管理 |
| 第3层 | 传输层 | TCP(可靠)、UDP(快速) | 端口号、重传机制 |
| 第2层 | 网络层 | IP、ICMP、路由 | IP地址、子网掩码 |
| 第1层 | 网络接口层 | WiFi MAC、LTE RRC、以太网 | 信号强度、链路状态 |
我在做嵌入式网关项目时遇到过一个问题:设备上报数据偶尔丢失,查了三天,最后发现是传输层TCP窗口设置太小,加上WiFi信号波动导致频繁重传。嗯,从那以后我养成了一个习惯——先看传输层,再看应用层。
核心要点:WiFi配网和LTE切换,本质上是网络接口层(第1层)的切换,但应用层(第4层)的会话必须保持。这就是为什么我们要理解协议栈——切换链路,但不能断连接。
2.2 Socket编程基础——应用与协议栈的接口
Socket,说白了就是操作系统给应用层开的一扇门。你写代码往Socket里丢数据,操作系统帮你封装成TCP段、IP包,最后通过网卡发出去。
我个人习惯把Socket编程分为三步走:
- 创建Socket——指定协议族(AF_INET)、类型(SOCK_STREAM/SOCK_DGRAM)
- 建立连接——客户端connect(),服务端bind()+listen()+accept()
- 收发数据——send()/recv() 或 write()/read()
来看一个最简的TCP客户端示例,我当年入门时就是靠这段代码打通了任督二脉:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888);
inet_pton(AF_INET, "192.168.1.100", &server_addr.sin_addr);
connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
char *msg = "Hello, IoT World!";
send(sock, msg, strlen(msg), 0);
char buffer[1024] = {0};
recv(sock, buffer, sizeof(buffer), 0);
printf("Received: %s\n", buffer);
close(sock);
避坑指南:我曾经在WiFi配网场景下直接用阻塞式Socket,结果配网过程中网络切换导致connect()卡死30秒。后来我改用非阻塞模式+select()超时机制,问题迎刃而解。记住:物联网设备不能死等。
2.3 HTTP/HTTPS协议——RESTful通信的基石
HTTP协议,大家每天都在用。但物联网场景下,HTTP有几个特点需要特别注意:
- 请求-响应模型:客户端主动发起,服务端被动响应。设备要上报数据,必须自己先连服务器。
- 无状态:每次请求独立,服务器不保存客户端上下文。嗯,这意味着你每次都要带Token或Session ID。
- HTTPS = HTTP + TLS:多了证书验证和加密传输。配网场景下,HTTPS能防止中间人攻击。
你想想看,一个智能插座要上报当前功率,用HTTP POST发一段JSON:
POST /api/v1/device/data HTTP/1.1
Host: iot.example.com
Content-Type: application/json
Authorization: Bearer xxxxxx
{
"device_id": "sock_001",
"power_w": 12.5,
"timestamp": 1712345678
}
服务端返回200 OK,表示接收成功。简单、直接,但有个问题——如果WiFi断了,HTTP请求就失败了,你得自己实现重试逻辑。
注意:HTTPS的TLS握手需要2-3个RTT(往返时间),在WiFi信号弱或LTE切换时,握手可能超时。我建议在切换完成后延迟1-2秒再发起HTTPS请求,给协议栈一点稳定时间。
2.4 MQTT协议简介——物联网消息的轻骑兵
MQTT,全称Message Queuing Telemetry Transport,是IBM开发的轻量级发布/订阅协议。为什么它在物联网领域这么火?说白了,就三个字:轻、快、省。
| 特性 | HTTP | MQTT |
|---|---|---|
| 协议头最小开销 | ~800字节 | 2字节 |
| 通信模型 | 请求-响应 | 发布-订阅 |
| 服务质量 | 无(依赖TCP) | QoS 0/1/2 |
| 保活机制 | 无 | PINGREQ/PINGRESP |
| 适合场景 | Web、REST API | 传感器、控制、推送 |
MQTT的核心概念就三个:
- Broker(代理):消息中转站,所有客户端都连到Broker
- Topic(主题):消息的分类标签,比如
home/livingroom/temperature - QoS(服务质量):0最多发一次,1至少发一次,2恰好发一次
我在一个智能家居项目中,用MQTT做设备控制。设备通过WiFi连上Broker,订阅 device/sock_001/cmd 主题。手机App发布一条消息到该主题,设备收到后执行开关动作。整个过程消息体只有几个字节,比HTTP省太多了。
关键点:MQTT的保活机制(Keep Alive)对WiFi配网和LTE切换非常友好。设备每隔一段时间发PINGREQ,Broker回复PINGRESP。如果网络切换导致连接断开,Broker会在超时后发送Will Message(遗嘱消息),通知其他客户端该设备离线了。这个机制我用了很多年,非常可靠。
2.5 本章知识体系总览
下面这张图是我自己画的,把这一节的核心知识点串在了一起。你把它存下来,后面做配网和切换时随时回来对照。
我的建议:学完这一节,你最好能自己动手写一个TCP Socket客户端,然后用MQTT客户端连上公共Broker(比如test.mosquitto.org)收发几条消息。实践出真知,光看不动手,永远记不住。