清空/重置队列

(1)首先关闭rabbitmq: rabbitmqctl stop_app

(2)还原: rabbitmqctl reset

(3)启动: rabbitmqctl start_app

(4)添加用户: rabbitmqctl add_user root root

(5)设置权限:rabbitmqctl set_permissions -p / root ".*" ".*" ".*"

(6)查看用户: rabbitmqctl list_users

-----------------------------------------------以上为早期的从网上找的方法,如果仅是清空某个队列则用

rabbitmqctl  purge_queue  QueueName

这样就可以清空指定的队列

转载于:https://www.cnblogs.com/mysic/p/6148352.html

unsigned int mqtt_parser(CircularQueue *q, uint8_t *packet_buff) { // 静态变量:跨函数调用保持状态 static uint8_t state = 0; // 解析状态机当前状态 static uint32_t total_length = 0; // 待解析报文的总长度(固定报头+剩余长度+负载) static uint8_t remaining_length_bytes = 0; // 剩余长度字段占用的字节数 static uint8_t time_out = 0; // 超时计数器(连续未完整解析的次数) // 局部变量 uint8_t packet_type; // MQTT报文类型(存储在固定报头的第1个字节) uint8_t byte; // 临时存储从队列读取的字节 uint8_t multiplier; // 剩余长度解码时的乘数(1, 128, 128^2, 128^3) uint8_t remaining_length; // 解析出的剩余长度(不包含固定报头和剩余长度字段本身) uint32_t current_offset; // 当前正在解析的字节在队列中的偏移量 uint32_t i; // 循环计数器 while (1) { // 检查队列中是否有足够的基础数据(至少需要2字节才能开始解析) if (Queue_Length(q) < 2) { return 0; // 数据不足,等待更多数据 } // 状态机处理 switch (state) { case 0: // 解析固定报头和剩余长度 // 读取固定报头的第1个字节(包含报文类型和标志位) Queue_PeekAt(q, 0, &packet_type); LOG_PRINTF("[MQTT Parser] Processing packet type: 0x%02X\n", packet_type); // 验证报文类型是否合法 if (!validate_packet_header(packet_type)) { LOG_PRINTF("[MQTT Parser] Invalid packet header: 0x%02X\n", packet_type); Queue_MoveReadIndex(q, 1); // 丢弃无效字节 state = 0; time_out = 0; return 0; } // 初始化剩余长度解析相关变量 multiplier = 1; // 初始乘数为1(128^0) total_length = 0; // 重置总长度 remaining_length_bytes = 0; // 重置剩余长度字节计数器 remaining_length = 0; // 重置剩余长度 // 解析剩余长度字段(可能占用1~4字节) do { // 检查队列中是否有足够数据读取下一个剩余长度字节 if (Queue_Length(q) < (1 + remaining_length_bytes + 1)) { return 0; // 数据不足,等待更多数据 } // 计算当前剩余长度字节的偏移量(固定报头1字节 + 已解析的剩余长度字节数) current_offset = 1 + remaining_length_bytes; Queue_PeekAt(q, current_offset, &byte); // 读取当前剩余长度字节 // 解码剩余长度(每个字节的低7位是有效数据,最高位是继续标志) remaining_length += (byte & 0x7F) * multiplier; multiplier *= 128; // 乘数递增(1, 128, 128^2, 128^3) remaining_length_bytes++; // 剩余长度字节计数器递增 // 协议合规性检查:剩余长度最多占用4字节 if (remaining_length_bytes >= 4 && (byte & 0x80)) { LOG_PRINTF("[MQTT Parser] Invalid remaining length (exceeds 4 bytes)\n"); Queue_MoveReadIndex(q, 1 + remaining_length_bytes); // 丢弃错误报文 state = 0; time_out = 0; return 0; } } while (byte & 0x80); // 继续循环直到遇到剩余长度的最后一个字节(最高位为0) // 计算完整报文长度:固定报头(1字节) + 剩余长度字节数 + 剩余长度 total_length = 1 + remaining_length_bytes + remaining_length; LOG_PRINTF("[MQTT Parser] Packet length: %u bytes\n", total_length); // 切换到状态1,准备读取完整报文 state = 1; break; case 1: // 读取完整报文 // 检查队列中是否有完整的报文数据 if (Queue_Length(q) < total_length) { // 超时处理:连续MAX_TIMEOUT_COUNT次未能解析出完整报文,则丢弃1字节(防止队列被无效数据阻塞) time_out++; if (time_out >= MAX_TIMEOUT_COUNT) { LOG_PRINTF("[MQTT Parser] Timeout, discard 1 byte\n"); Queue_MoveReadIndex(q, 1); // 移动读指针,丢弃1字节 state = 0; // 重置状态机 time_out = 0; // 重置超时计数器 return 0; } return 0; // 数据不足,等待更多数据 } // 批量读取报文数据到输出缓冲区 for (i = 0; i < total_length; i++) { Queue_PeekAt(q, i, &packet_buff[i]); LOG_PRINTF("%02X ", packet_buff[i]); // 调试输出:打印报文字节 } printf("\n"); // 移动队列读指针,丢弃已读取的报文数据 Queue_MoveReadIndex(q, total_length); // 重置状态机和超时计数器 state = 0; time_out = 0; // 返回解析成功的报文长度 return total_length; default: // 未知状态,重置状态机 LOG_PRINTF("[MQTT Parser] Unknown state, resetting\n"); state = 0; time_out = 0; return 0; } } } 现在我将超时处理放到CASE1中,并且我想增加超时移除以读取的数据
07-13
/** * @brief MQTT协议报文解析器 * @param q 循环队列指针,存储待解析的MQTT报文数据 * @param packet_buff 输出缓冲区,用于存储解析出的完整MQTT报文 * @return 解析成功的报文长度(字节数),返回0表示解析失败或数据不足 */ unsigned int mqtt_parser(CircularQueue *q, uint8_t *packet_buff) { // 静态变量:跨函数调用保持状态 static uint8_t state = 0; // 解析状态机当前状态 static uint32_t total_length = 0; // 待解析报文的总长度(固定报头+剩余长度+负载) static uint8_t remaining_length_bytes = 0; // 剩余长度字段占用的字节数 static uint8_t time_out = 0; // 超时计数器(连续未完整解析的次数) // 局部变量 uint8_t packet_type; // MQTT报文类型(存储在固定报头的第1个字节) uint8_t byte; // 临时存储从队列读取的字节 uint8_t multiplier; // 剩余长度解码时的乘数(1, 128, 128^2, 128^3) uint8_t remaining_length; // 解析出的剩余长度(不包含固定报头和剩余长度字段本身) uint32_t current_offset; // 当前正在解析的字节在队列中的偏移量 uint32_t i; // 循环计数器 while (1) { // 检查队列中是否有足够的基础数据(至少需要2字节才能开始解析) if (Queue_Length(q) < 2) { return 0; // 数据不足,等待更多数据 } // 状态机处理 switch (state) { case 0: // 解析固定报头和剩余长度 // 读取固定报头的第1个字节(包含报文类型和标志位) Queue_PeekAt(q, 0, &packet_type); LOG_PRINTF("[MQTT Parser] Processing packet type: 0x%02X\n", packet_type); // 验证报文类型是否合法 if (!validate_packet_header(packet_type)) { LOG_PRINTF("[MQTT Parser] Invalid packet header: 0x%02X\n", packet_type); Queue_MoveReadIndex(q, 1); // 丢弃无效字节 state = 0; time_out = 0; return 0; } // 初始化剩余长度解析相关变量 multiplier = 1; // 初始乘数为1(128^0) total_length = 0; // 重置总长度 remaining_length_bytes = 0; // 重置剩余长度字节计数器 remaining_length = 0; // 重置剩余长度 // 解析剩余长度字段(可能占用1~4字节) do { // 检查队列中是否有足够数据读取下一个剩余长度字节 if (Queue_Length(q) < (1 + remaining_length_bytes + 1)) { return 0; // 数据不足,等待更多数据 } // 计算当前剩余长度字节的偏移量(固定报头1字节 + 已解析的剩余长度字节数) current_offset = 1 + remaining_length_bytes; Queue_PeekAt(q, current_offset, &byte); // 读取当前剩余长度字节 // 解码剩余长度(每个字节的低7位是有效数据,最高位是继续标志) remaining_length += (byte & 0x7F) * multiplier; multiplier *= 128; // 乘数递增(1, 128, 128^2, 128^3) remaining_length_bytes++; // 剩余长度字节计数器递增 // 协议合规性检查:剩余长度最多占用4字节 if (remaining_length_bytes >= 4 && (byte & 0x80)) { LOG_PRINTF("[MQTT Parser] Invalid remaining length (exceeds 4 bytes)\n"); Queue_MoveReadIndex(q, 1 + remaining_length_bytes); // 丢弃错误报文 state = 0; time_out = 0; return 0; } } while (byte & 0x80); // 继续循环直到遇到剩余长度的最后一个字节(最高位为0) // 计算完整报文长度:固定报头(1字节) + 剩余长度字节数 + 剩余长度 total_length = 1 + remaining_length_bytes + remaining_length; LOG_PRINTF("[MQTT Parser] Packet length: %u bytes\n", total_length); state = 1; break; case 1: // 检查数据是否完整、超时处理 // 检查队列中是否有完整的报文数据 if (Queue_Length(q) < total_length) { // 超时处理:给一个比较长的超时时间,如果队列中的数据量都还达不到报文长度,则丢弃所有数据 time_out++; if (time_out >= MAX_TIMEOUT_COUNT) { if(Queue_Length(q) < total_length) { LOG_PRINTF("[MQTT Parser] Timeout, discard all byte\n"); Queue_MoveReadIndex(q, Queue_Length(q)); // 移动读指针,丢弃当前队列中所有数据 state = 0; // 重置状态机 time_out = 0; // 重置超时计数器 return 0; } } return 0; // 数据不足,等待更多数据 } else // 数据完整,准备读取完整数据 { state = 2; break; } case 2: // 读取完整报文 // 批量读取报文数据到输出缓冲区 for (i = 0; i < total_length; i++) { Queue_PeekAt(q, i, &packet_buff[i]); LOG_PRINTF("%02X ", packet_buff[i]); // 调试输出:打印报文字节 } printf("\n"); // 移动队列读指针,丢弃已读取的报文数据 Queue_MoveReadIndex(q, total_length); // 重置状态机和超时计数器 state = 0; time_out = 0; // 返回解析成功的报文长度 return total_length; default: // 未知状态,重置状态机 LOG_PRINTF("[MQTT Parser] Unknown state, resetting\n"); state = 0; time_out = 0; return 0; } } }状态0:初始状态,检查数据类型,获取报文长度 状态1:等待剩余长度解析完成,并检查报文合法性 状态2:等待完整报文数据 在状态0中,我们主要检查报文头(固定头第一个字节)的合法性,并解析剩余长度(第二个字节开始的可变长度整数)。同时,我们需要处理超时情况,如果在一定时间内没有解析出剩余长度,则丢弃已读取的报头部分(包括固定头第一个字节和已经读到的剩余长度字节)并回到初始状态。增加一个变量记录转到状态1时队列长度,用来判断有没有数据加入。 在状态1中,我们已经解析出了剩余长度,因此知道了整个报文的长度(1字节固定头+剩余长度字节数+剩余长度表示的数据长度)。此时,我们判断队列中数据是否足够组成一个完整报文。如果不够,则等待,并启动超时计时。超时分为两种情况: a) 在等待过程中有新数据加入,(有可能是新报文)但是直到超时仍然不够,所以只能丢弃报头部分(1+剩余长度字节数)并回到状态0。 b) 在等待过程中没有新数据加入(即队列数据量一直不变),则清空队列并回到状态0。 当数据足够时,进入状态2,从队列中取出完整报文。 注意:上述代码中,状态0和状态1、2是连续的,在状态0解析完报头后,直接进入状态1,然后如果状态1中数据足够,又直接进入状态2,所以用switch case时,状态0和状态1后面没有break,会继续执行后面的状态。这样设计是为了在一次调用中尽可能完成报文的提取。 按照要求更改这个代码
07-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值