Mosquitto 中 packet_mosq.c 文件的功能分析
整体目的: packet_mosq.c 是 Mosquitto MQTT 库的核心文件,主要负责 MQTT 数据包的内存管理、分配、清理、队列操作,以及从网络套接字读取和写入数据包。它处理 MQTT 协议中的数据包结构,包括命令、剩余长度编码,以及与 WebSockets 的集成。该文件确保数据包在客户端或经纪人端高效传输,支持 MQTT 协议的各种控制包(如 CONNECT、PUBLISH 等)。它还包括错误处理和大小检查,以防止超大包或内存问题。
主要函数列表及描述(基于代码和注释):
- packet__alloc(struct mosquitto__packet *packet): 分配数据包的内存,包括计算和编码剩余长度(remaining length),并初始化负载(payload)。如果剩余长度超过限制,返回 MOSQ_ERR_PAYLOAD_SIZE 错误。支持 WebSockets 的额外预留空间。
- packet__cleanup(struct mosquitto__packet *packet): 清理单个数据包,重置命令、长度等字段,并释放负载内存。
- packet__cleanup_all_no_locks(struct mosquitto *mosq): 清理 Mosquitto 上下文中的所有出站数据包(out_packet),不使用锁,适用于非多线程场景。
- packet__queue(struct mosquitto *mosq, struct mosquitto__packet *packet): 将数据包添加到出站队列(out_packet)中。如果当前有正在处理的包,则追加到队列尾部,并更新计数。
- packet__check_oversize(struct mosquitto *mosq, uint32_t remaining_length): 检查数据包是否超过客户端或经纪人的最大包大小限制(max_packet_size)。如果超过,返回 MOSQ_ERR_OVERSIZE_PACKET 错误。
- packet__read(struct mosquitto *mosq, struct mosquitto__packet *packet): 从网络套接字读取数据包,包括处理剩余长度和负载。更新接收字节统计,并处理部分读取的情况。
- packet__write(struct mosquitto *mosq): 将出站数据包写入网络套接字。处理部分写入、WebSockets 头,并更新发送字节统计。如果写入失败,返回错误如 MOSQ_ERR_NO_CONN。
- packet__prep(struct mosquitto__packet *packet): 为 WebSockets 准备数据包,添加 LWS_PRE 预留空间并调整负载位置(仅在 WITH_WEBSOCKETS 启用时有效)。
关键数据结构和宏:
- struct mosquitto__packet: 数据包结构体,包括命令(command)、位置(pos)、剩余长度(remaining_length)、负载(payload)等。
- WITH_WEBSOCKETS: 宏,用于条件编译 WebSockets 支持,包括 libwebsockets 集成。
- G_BYTES_RECEIVED_INC / G_BYTES_SENT_INC: 宏,用于更新全局字节统计(仅在 WITH_BROKER 模式下有效)。
- MOSQ_ERR_***: 各种错误码,如 MOSQ_ERR_NOMEM(内存不足)、MOSQ_ERR_PAYLOAD_SIZE(负载过大)。
Mosquitto 中 packet_datatypes.c 文件的功能分析
整体目的: packet_datatypes.c 专注于 MQTT 数据包中基本数据类型的读写操作,包括字节、字符串、uint16/uint32、变长整数(varint)和二进制数据。这些函数是低级辅助工具,用于构建和解析 MQTT 控制包的变量头和负载部分。它确保数据符合 MQTT 协议规范(如变长整数编码不超过 4 字节),并处理错误如畸形包(MOSQ_ERR_MALFORMED_PACKET)。该文件是 packet_mosq.c 的补充,支持高效的序列化和反序列化。
主要函数列表及描述(基于代码和注释):
- packet__read_byte(struct mosquitto__packet *packet, uint8_t *byte): 从数据包负载中读取一个字节。如果位置超出剩余长度,返回 MOSQ_ERR_MALFORMED_PACKET 错误。
- packet__write_byte(struct mosquitto__packet *packet, uint8_t byte): 向数据包负载写入一个字节。确保位置不超过包长度。
- packet__read_bytes(struct mosquitto__packet *packet, void *bytes, uint32_t count): 从数据包读取指定数量的字节到缓冲区。如果超出剩余长度,返回畸形包错误。
- packet__write_bytes(struct mosquitto__packet *packet, const void *bytes, uint32_t count): 向数据包写入指定数量的字节。确保位置不超过包长度。
- **packet__read_binary(struct mosquitto__packet *packet, uint8_t data, uint16_t *length): 读取二进制数据,先读 uint16 长度,然后读取相应数据。分配内存给 data,如果失败返回 MOSQ_ERR_NOMEM。
- packet__write_varint(struct mosquitto__packet *packet, uint32_t word): 向数据包写入变长整数(variable integer),编码为 1-4 字节。如果超过 268435455,返回 MOSQ_ERR_INVAL。
- packet__read_varint(struct mosquitto__packet *packet, uint32