2、常见协议基础:HTTP/HTTPS、TCP/UDP、MQTT、WebSocket

做协议适配,说白了就是跟各种协议打交道。你得知道它们各自是什么脾气,才能让它们好好配合。这一章我把工作中最常用的几个协议拎出来聊聊,都是我实际项目里反复用到的。

2.1 HTTP/HTTPS——最熟悉的陌生人

HTTP 大家肯定不陌生,浏览器里天天见。但做适配的时候,很多人只记得 GET 和 POST,其他细节全忘了。我个人习惯把 HTTP 看作一个「请求-响应」的对话模型:客户端说一句,服务端回一句,说完就断。

核心要点:HTTP 是无状态协议,每次请求都是独立的。服务器不会记住你上次说了什么。

2.1.1 请求报文结构

一个标准的 HTTP 请求长这样:

POST /api/device/data HTTP/1.1
Host: 192.168.1.100:8080
Content-Type: application/json
Authorization: Bearer xxxxxx
Content-Length: 45

{"temperature": 25.6, "humidity": 60}

注意看,第一行是请求行,中间是头部,空行之后是正文。我在项目中遇到过不少新手把空行漏掉,结果服务端一直收不到正文——嗯,这个坑我当年也踩过。

2.1.2 HTTPS 多了什么?

HTTPS 就是在 HTTP 外面套了一层 TLS/SSL。说白了,就是把明文对话变成了加密通话。握手阶段会交换证书、协商密钥,之后所有数据都是加密传输的。

避坑指南:我曾经在嵌入式设备上做 HTTPS 适配,发现设备时间不准导致证书验证失败。后来我养成了一个习惯——任何 HTTPS 适配,先检查系统时间对不对。

2.2 TCP/UDP——传输层的两个极端

TCP 和 UDP 是传输层的两大支柱。你想想看,一个像快递员送货上门还要你签字确认,另一个像广播喇叭喊一嗓子就不管了。两者各有各的用处。

特性 TCP UDP
连接方式 面向连接(三次握手) 无连接
可靠性 可靠传输,有重传机制 不可靠,丢包不重传
顺序性 保证数据按序到达 不保证顺序
速度 相对较慢 快,低延迟
典型应用 HTTP、FTP、SSH DNS、视频直播、游戏

2.2.1 TCP 三次握手——别嫌它啰嗦

我刚开始做网络编程时,觉得三次握手太啰嗦了。后来在工业现场做数据采集,网络环境极差,丢包率动不动就 10%。这时候 TCP 的重传和保序机制就救命了。

// 伪代码:TCP 客户端连接
client = socket(AF_INET, SOCK_STREAM, 0)
client.connect(("192.168.1.10", 8080))  // 这里会触发三次握手
client.send(data)
client.close()

注意:TCP 的粘包问题。因为 TCP 是流式协议,多个小包可能合并成一个发送。做适配时一定要自己定义消息边界,比如用固定长度头部或者特殊分隔符。

2.2.2 UDP——快但不靠谱

UDP 适合那些能容忍丢包但不能容忍延迟的场景。比如视频通话,偶尔花屏一下可以接受,但卡顿就受不了。我在做智能家居网关时,设备状态上报就用 UDP——丢了就丢了,下次上报会覆盖。

2.3 MQTT——物联网的标配

MQTT 是发布/订阅模式的轻量级协议,特别适合物联网场景。说白了,就是有个中间人(Broker)帮你转发消息,发送方和接收方不用直接认识。

2.3.1 三个角色

  • Broker(代理):消息中转站,负责接收和分发
  • Publisher(发布者):发送消息到某个主题
  • Subscriber(订阅者):订阅感兴趣的主题,接收消息

2.3.2 三个 QoS 等级

MQTT 提供了三个服务质量等级,我一般这么选:

  • QoS 0:最多发一次,丢了不管。适合传感器定期上报,丢了等下次
  • QoS 1:至少发一次,可能重复。适合控制指令,重复了设备做幂等处理就行
  • QoS 2:恰好发一次,最可靠但最慢。适合计费、报警等关键消息

个人经验:我在做车联网项目时,车辆位置上报用 QoS 0,远程锁车指令用 QoS 2。千万别把关键指令设成 QoS 0,我曾经见过有人这么干,结果指令丢了车锁不上——那场面,你懂的。

2.3.3 保留消息与遗嘱

这两个特性很实用。保留消息让新订阅者能立即拿到最新数据,不用等下次发布。遗嘱消息则是设备异常断开时,Broker 帮它发一条遗言。我在做设备状态监控时,就用遗嘱来检测设备离线。

2.4 WebSocket——全双工的救星

HTTP 是「你问我答」的模式,服务器不能主动给客户端发消息。但很多场景需要实时推送,比如聊天、行情、游戏。WebSocket 就是来解决这个问题的。

2.4.1 握手过程

WebSocket 的握手是用 HTTP 升级来的。客户端发一个 Upgrade 请求,服务器同意后,连接就变成了全双工模式。

// 客户端握手请求
GET /ws HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

// 服务器响应
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

2.4.2 数据帧格式

WebSocket 的数据是帧格式的,有掩码、操作码、长度等字段。做适配时要注意:客户端发数据必须加掩码,服务器端不用。这个细节我当年调试了半天才发现。

核心区别:HTTP 是半双工,WebSocket 是全双工。HTTP 每次请求都要建连,WebSocket 建连一次就能双向通信。

2.5 协议对比与选型

做协议适配时,选对协议比写对代码更重要。我整理了一个对比表,方便你快速决策:

场景 推荐协议 理由
Web API 调用 HTTP/HTTPS 成熟、工具多、防火墙友好
实时推送 WebSocket 低延迟、全双工
物联网传感器 MQTT 轻量、省电、支持海量设备
视频/语音流 UDP 容忍丢包、低延迟
文件传输 TCP 必须可靠、顺序到达

2.6 协议关系全景图

下面这张图展示了这些协议在 OSI 模型中的位置和关系。我每次做适配前都会看一眼这张图,确认自己在哪一层干活。

常见协议关系全景图 应用层 HTTP/HTTPS MQTT WebSocket 其他应用层协议 传输层 TCP(可靠、有序) UDP(快速、不可靠) 网络层(IP) 说明:HTTP/HTTPS、WebSocket 基于 TCP;MQTT 通常基于 TCP,也可选 UDP 版本 做协议适配时,先确定传输层用 TCP 还是 UDP,再选应用层协议

2.7 小结

这一章我们聊了四种常见协议。HTTP/HTTPS 是 Web 的基石,TCP/UDP 是传输层的左右手,MQTT 是物联网的标配,WebSocket 是实时通信的利器。做协议适配时,我的建议是:先搞清楚业务场景需要什么特性——可靠性、实时性、还是低功耗?然后对照上面的表格选协议,最后再动手写代码。