基于STM32实现MQTT

2023-11-09

最近一个项目中要用到MQTT或者CoAP,比较了两个的优缺点后。最后选择了MQTT,由于是第一次接触这个协议,在学习中遇到了不少的坑,所以分享出来。第一次写博客,有错勿怪。

1、MQTT协议

    MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。

   协议详情: MQTT Version 3.1.1(英文版)

                    (中文版)

2、STM32实现的自我理解

   既然是一个协议,所以有一个基本的物理网络层就可以实现

   将就手上的一个ESP8266无线wifi串口模块,一个STM32的板子。也就可以完成MQTT的测试了。

   一般来说在协议中扮演的是一个客户端。主要的工作就是连接服务器、订阅消息、发送消息几个功能。最开始我在网上找了MQTT的客户端代码包,打开一看就蒙了。太多、太杂了,完全大于了我们的需求。所以我自己通过抓包对着协议写了一个数据包生成代码。

3、测试前准备

   MQTT服务器:我用的是Apollo Console(账号默认为:admin 密码默认:password 后面连接时要用)

   MQTT客户端: 通信猫。

   具体怎么用大家百度。。。

4、代码实现

4.1、固定报头 Fixed header

类型:

标志位:

根据这个可以写一个生成固定头的函数

 
  1. #define MQTT_TypeCONNECT 1//请求连接

  2. #define MQTT_TypeCONNACK 2//请求应答

  3. #define MQTT_TypePUBLISH 3//发布消息

  4. #define MQTT_TypePUBACK 4//发布应答

  5. #define MQTT_TypePUBREC 5//发布已接收,保证传递1

  6. #define MQTT_TypePUBREL 6//发布释放,保证传递2

  7. #define MQTT_TypePUBCOMP 7//发布完成,保证传递3

  8. #define MQTT_TypeSUBSCRIBE         8//订阅请求

  9. #define MQTT_TypeSUBACK 9//订阅应答

  10. #define MQTT_TypeUNSUBSCRIBE                 10//取消订阅

  11. #define MQTT_TypeUNSUBACK 11//取消订阅应答

  12. #define MQTT_TypePINGREQ 12//ping请求

  13. #define MQTT_TypePINGRESP 13//ping响应

  14. #define MQTT_TypeDISCONNECT                 14//断开连接

  15. unsigned char GetDataFixedHead(unsigned char MesType,unsigned char DupFlag,unsigned char QosLevel,unsigned char Retain)

  16. {

  17. unsigned char dat = 0;

  18. dat = (MesType & 0x0f) << 4;

  19. dat |= (DupFlag & 0x01) << 3;

  20. dat |= (QosLevel & 0x03) << 1;

  21. dat |= (Retain & 0x01);

  22. return dat;

  23. }

 

4.2、连接

连接时抓的包的:

根据协议分析

 

固定报头 Fixed header

也就是数据包前两个10 21

后面是可变头:协议名、协议级别、连接标志、清除会话、遗嘱标志、遗嘱、遗嘱保留、用户名标志、密码标志、保持连接。

然后是有效载荷:客户端标识符、遗嘱主题、遗嘱消息、用户名、密码。

 
  1. #define MQTT_StaCleanSession 1 //清理会话

  2. #define MQTT_StaWillFlag 0 //遗嘱标志

  3. #define MQTT_StaWillQoS 0 //遗嘱QoS连接标志的第4和第3位。

  4. #define MQTT_StaWillRetain 0 //遗嘱保留

  5. #define MQTT_StaUserNameFlag 1 //用户名标志 User Name Flag

  6. #define MQTT_StaPasswordFlag 1 //密码标志 Password Flag

  7. #define MQTT_KeepAlive         60       //心跳包秒数

  8. #define MQTT_ClientIdentifier         "test"                          //客户端标识符 Client Identifier

  9. #define MQTT_WillTopic "" //遗嘱主题 Will Topic

  10. #define MQTT_WillMessage "" //遗嘱消息 Will Message

  11. #define MQTT_UserName "admin" //用户名 User Name

  12. #define MQTT_Password "password" //密码 Password

  13. void GetDataConnet(unsigned char *buff)//获取连接的数据包正确连接返回20 02 00 00

  14. {

  15. unsigned int i,len,lennum = 0;

  16. unsigned char *msg;

  17. buff[0] = GetDataFixedHead(MQTT_TypeCONNECT,0,0,0);

  18. buff[2] = 0x00;

  19. buff[3] = 0x04;

  20. buff[4] = 'M';

  21. buff[5] = 'Q';

  22. buff[6] = 'T';

  23. buff[7] = 'T';

  24. buff[8] = 0x04;//协议级别 Protocol Level

  25. buff[9] = 0 | (MQTT_StaCleanSession << 1) | (MQTT_StaWillFlag << 1)

  26.     | (MQTT_StaWillQoS << 3) | (MQTT_StaWillRetain << 5)

  27.     | (MQTT_StaPasswordFlag << 6) |(MQTT_StaUserNameFlag << 7);//连接标志

  28. buff[10] = MQTT_KeepAlive >> 8;

  29. buff[11] = MQTT_KeepAlive;

  30. len = strlen(MQTT_ClientIdentifier);

  31. buff[12] = len >> 8;

  32. buff[13] = len;

  33. msg = MQTT_ClientIdentifier;

  34. for(i = 0;i<len;i++)

  35. {

  36. buff[14+i] = msg[i];

  37. }

  38. lennum += len;

  39. if(MQTT_StaWillFlag)

  40. {

  41. len = strlen(MQTT_WillTopic);

  42. buff[13 + lennum + 1] = len >> 8;

  43. buff[13 + lennum + 2] = len;

  44. lennum += 2;

  45. msg = MQTT_WillTopic;

  46. for(i = 0;i<len;i++)

  47. {

  48. buff[14+lennum+i] = msg[i];

  49. }

  50. lennum += len;

  51. len = strlen(MQTT_WillMessage);

  52. buff[12] = len >> 8;

  53. buff[13] = len;

  54. lennum += 2;

  55. msg = MQTT_WillMessage;

  56. for(i = 0;i<len;i++)

  57. {

  58. buff[14+lennum+i] = msg[i];

  59. }

  60. lennum += len;

  61. }

  62. if(MQTT_StaUserNameFlag)

  63. {

  64. len = strlen(MQTT_UserName);

  65. buff[13 + lennum + 1] = len >> 8;

  66. buff[13 + lennum + 2] = len;

  67. lennum += 2;

  68. msg = MQTT_UserName;

  69. for(i = 0;i<len;i++)

  70. {

  71. buff[14+lennum+i] = msg[i];

  72. }

  73. lennum += len;

  74.  
  75. }

  76. if(MQTT_StaPasswordFlag)

  77. {

  78. len = strlen(MQTT_Password);

  79. buff[13 + lennum + 1] = len >> 8;

  80. buff[13 + lennum + 2] = len;

  81. lennum += 2;

  82. msg = MQTT_Password;

  83. for(i = 0;i<len;i++)

  84. {

  85. buff[14+lennum+i] = msg[i];

  86. }

  87. lennum += len;

  88. }

  89. buff[1] = 13 + lennum - 1;//最后计算长度

  90. }

4.3、订阅主题

订阅a/b时抓的包:

 
  1. /**********************

  2. 订阅主题的数据包

  3. Num:主题序号 (每次连接从1开始)

  4. RequestedQoS:服务质量要求0,1或2

  5. **********************/

  6. void GetDataSUBSCRIBE(unsigned char *buff,const char *dat,unsigned int Num,unsigned char RequestedQoS)

  7. {

  8. unsigned int i,len = 0,lennum = 0;

  9. buff[0] = 0x82;

  10. len = strlen(dat);

  11. buff[2] = Num>>8;

  12. buff[3] = Num;

  13. buff[4] = len>>8;

  14. buff[5] = len;

  15. for(i = 0;i<len;i++)

  16. {

  17. buff[6+i] = dat[i];

  18. }

  19. lennum = len;

  20. buff[6 + lennum ] = RequestedQoS;

  21. buff[1] = lennum + 5;

  22. }

4.4、发布信息

固定报头:

 

 

 

发送a/c主题信息为123时抓的包:

 

 

 
  1. /**************************************

  2. buff:数据包数组

  3. dup :重发标志

  4. qos :服务质量等级

  5. retain:保留标志

  6. topic:主题如“a/c”

  7. msg:消息

  8. ************************************/

  9. void GetDataPUBLISH(unsigned char *buff,unsigned char dup, unsigned char qos,unsigned char retain,const char *topic ,const char *msg)

  10. {   

  11.         unsigned int i,len=0,lennum=0;

  12. buff[0] = GetDataFixedHead(MQTT_TypePUBLISH,dup,qos,retain);

  13. len = strlen(topic);

  14. buff[2] = len>>8;

  15. buff[3] = len;

  16. for(i = 0;i<len;i++)

  17. {

  18. buff[4+i] = topic[i];

  19. }

  20. lennum = len;

  21. len = strlen(msg);

  22. for(i = 0;i<len;i++)

  23. {

  24. buff[4+i+lennum] = msg[i];

  25. }

  26. lennum += len;

  27. buff[1] = lennum + 2;

  28. }

4.5、心跳请求

客户端发送PINGREQ报文给服务端的。

用于:

    在没有任何其它控制报文从客户端发给服务的时,告知服务端客户端还活着。

    请求服务端发送 响应确认它还活着。

    使用网络以确认网络连接没有断开。

心跳请求抓的包:

可以看到就是发了一个C0 00

而服务器返回一个    d0 00

5、总结

    文中就讲了几个非常重要的请求格式。esp8266连接tcp服务器后就可以发送生成的数据包,就可以实现MQTT的功能。

    代码我已经测试过完全可用。

下面给完整的代码:

mqtt.h

 
  1. #ifndef __MQTT_H

  2. #define __MQTT_H

  3. #include "sys.h"

  4. #include <string.h>

  5. #define MQTT_TypeCONNECT 1//请求连接

  6. #define MQTT_TypeCONNACK 2//请求应答

  7. #define MQTT_TypePUBLISH 3//发布消息

  8. #define MQTT_TypePUBACK 4//发布应答

  9. #define MQTT_TypePUBREC 5//发布已接收,保证传递1

  10. #define MQTT_TypePUBREL 6//发布释放,保证传递2

  11. #define MQTT_TypePUBCOMP 7//发布完成,保证传递3

  12. #define MQTT_TypeSUBSCRIBE 8//订阅请求

  13. #define MQTT_TypeSUBACK 9//订阅应答

  14. #define MQTT_TypeUNSUBSCRIBE 10//取消订阅

  15. #define MQTT_TypeUNSUBACK 11//取消订阅应答

  16. #define MQTT_TypePINGREQ 12//ping请求

  17. #define MQTT_TypePINGRESP 13//ping响应

  18. #define MQTT_TypeDISCONNECT 14//断开连接

  19.  
  20. #define MQTT_StaCleanSession 1 //清理会话

  21. #define MQTT_StaWillFlag 0 //遗嘱标志

  22. #define MQTT_StaWillQoS 0 //遗嘱QoS连接标志的第4和第3位。

  23. #define MQTT_StaWillRetain 0 //遗嘱保留

  24. #define MQTT_StaUserNameFlag 1 //用户名标志 User Name Flag

  25. #define MQTT_StaPasswordFlag 1 //密码标志 Password Flag

  26. #define MQTT_KeepAlive 60

  27. #define MQTT_ClientIdentifier "Tan1" //客户端标识符 Client Identifier

  28. #define MQTT_WillTopic "" //遗嘱主题 Will Topic

  29. #define MQTT_WillMessage "" //遗嘱消息 Will Message

  30. #define MQTT_UserName "admin" //用户名 User Name

  31. #define MQTT_Password "password" //密码 Password

  32.  
  33. unsigned char GetDataFixedHead(unsigned char MesType,unsigned char DupFlag,unsigned char QosLevel,unsigned char Retain);

  34. void GetDataPUBLISH(unsigned char *buff,unsigned char dup, unsigned char qos,unsigned char retain,const char *topic ,const char *msg);//获取发布消息的数据包

  35. void GetDataSUBSCRIBE(unsigned char *buff,const char *dat,unsigned int Num,unsigned char RequestedQoS);//订阅主题的数据包 Num:主题序号 RequestedQoS:服务质量要求0,1或2

  36. void GetDataDisConnet(unsigned char *buff);//获取断开连接的数据包

  37. void GetDataConnet(unsigned char *buff);//获取连接的数据包正确连接返回20 02 00 00

  38. void GetDataPINGREQ(unsigned char *buff);//心跳请求的数据包成功返回d0 00

  39. #endif

mqtt.c

 
  1. #include "mqtt.h"

  2.  
  3. unsigned char GetDataFixedHead(unsigned char MesType,unsigned char DupFlag,unsigned char QosLevel,unsigned char Retain)

  4. {

  5. unsigned char dat = 0;

  6. dat = (MesType & 0x0f) << 4;

  7. dat |= (DupFlag & 0x01) << 3;

  8. dat |= (QosLevel & 0x03) << 1;

  9. dat |= (Retain & 0x01);

  10. return dat;

  11. }

  12. void GetDataConnet(unsigned char *buff)//获取连接的数据包正确连接返回20 02 00 00

  13. {

  14. unsigned int i,len,lennum = 0;

  15. unsigned char *msg;

  16. buff[0] = GetDataFixedHead(MQTT_TypeCONNECT,0,0,0);

  17. buff[2] = 0x00;

  18. buff[3] = 0x04;

  19. buff[4] = 'M';

  20. buff[5] = 'Q';

  21. buff[6] = 'T';

  22. buff[7] = 'T';

  23. buff[8] = 0x04;//协议级别 Protocol Level

  24. buff[9] = 0 | (MQTT_StaCleanSession << 1) | (MQTT_StaWillFlag << 1)

  25. | (MQTT_StaWillQoS << 3) | (MQTT_StaWillRetain << 5)

  26. | (MQTT_StaPasswordFlag << 6) |(MQTT_StaUserNameFlag << 7);//连接标志

  27. buff[10] = MQTT_KeepAlive >> 8;

  28. buff[11] = MQTT_KeepAlive;

  29. len = strlen(MQTT_ClientIdentifier);

  30. buff[12] = len >> 8;

  31. buff[13] = len;

  32. msg = MQTT_ClientIdentifier;

  33. for(i = 0;i<len;i++)

  34. {

  35. buff[14+i] = msg[i];

  36. }

  37. lennum += len;

  38. if(MQTT_StaWillFlag)

  39. {

  40. len = strlen(MQTT_WillTopic);

  41. buff[13 + lennum + 1] = len >> 8;

  42. buff[13 + lennum + 2] = len;

  43. lennum += 2;

  44. msg = MQTT_WillTopic;

  45. for(i = 0;i<len;i++)

  46. {

  47. buff[14+lennum+i] = msg[i];

  48. }

  49. lennum += len;

  50. len = strlen(MQTT_WillMessage);

  51. buff[12] = len >> 8;

  52. buff[13] = len;

  53. lennum += 2;

  54. msg = MQTT_WillMessage;

  55. for(i = 0;i<len;i++)

  56. {

  57. buff[14+lennum+i] = msg[i];

  58. }

  59. lennum += len;

  60. }

  61. if(MQTT_StaUserNameFlag)

  62. {

  63. len = strlen(MQTT_UserName);

  64. buff[13 + lennum + 1] = len >> 8;

  65. buff[13 + lennum + 2] = len;

  66. lennum += 2;

  67. msg = MQTT_UserName;

  68. for(i = 0;i<len;i++)

  69. {

  70. buff[14+lennum+i] = msg[i];

  71. }

  72. lennum += len;

  73.  
  74. }

  75. if(MQTT_StaPasswordFlag)

  76. {

  77. len = strlen(MQTT_Password);

  78. buff[13 + lennum + 1] = len >> 8;

  79. buff[13 + lennum + 2] = len;

  80. lennum += 2;

  81. msg = MQTT_Password;

  82. for(i = 0;i<len;i++)

  83. {

  84. buff[14+lennum+i] = msg[i];

  85. }

  86. lennum += len;

  87. }

  88. buff[1] = 13 + lennum - 1;

  89. }

  90. void GetDataDisConnet(unsigned char *buff)//获取断开连接的数据包

  91. {

  92. buff[0] = 0xe0;

  93. buff[1] = 0;

  94. }

  95. void GetDataPINGREQ(unsigned char *buff)//心跳请求的数据包成功返回d0 00

  96. {

  97. buff[0] = 0xc0;

  98. buff[1] = 0;

  99. }

  100. /*

  101. 成功返回90 0x 00 Num RequestedQoS

  102. */

  103. void GetDataSUBSCRIBE(unsigned char *buff,const char *dat,unsigned int Num,unsigned char RequestedQoS)//订阅主题的数据包 Num:主题序号 RequestedQoS:服务质量要求0,1或2

  104. {

  105. unsigned int i,len = 0,lennum = 0;

  106. buff[0] = 0x82;

  107. len = strlen(dat);

  108. buff[2] = Num>>8;

  109. buff[3] = Num;

  110. buff[4] = len>>8;

  111. buff[5] = len;

  112. for(i = 0;i<len;i++)

  113. {

  114. buff[6+i] = dat[i];

  115. }

  116. lennum = len;

  117. buff[6 + lennum ] = RequestedQoS;

  118. buff[1] = lennum + 5;

  119. }

  120. void GetDataPUBLISH(unsigned char *buff,unsigned char dup, unsigned char qos,unsigned char retain,const char *topic ,const char *msg)//获取发布消息的数据包

  121. {

  122. unsigned int i,len=0,lennum=0;

  123. buff[0] = GetDataFixedHead(MQTT_TypePUBLISH,dup,qos,retain);

  124. len = strlen(topic);

  125. buff[2] = len>>8;

  126. buff[3] = len;

  127. for(i = 0;i<len;i++)

  128. {

  129. buff[4+i] = topic[i];

  130. }

  131. lennum = len;

  132. len = strlen(msg);

  133. for(i = 0;i<len;i++)

  134. {

  135. buff[4+i+lennum] = msg[i];

  136. }

  137. lennum += len;

  138. buff[1] = lennum + 2;

  139. }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于STM32实现MQTT 的相关文章

  • 基于Spring Gateway路由判断器实现各种灰度发布场景

    文章目录 1 灰度发布实现 1 1 按随机用户的流量百分比实现灰度 1 2 按人群划分实现的灰度 1 2 1 通过Header信息实现灰度 1 2 2 通过Query信息实现灰度 1 2 3 通过RemoteAdd判断来源IP实现灰度 2
  • django中models field详解

    本文参考自 django官方文档models field 在model中添加字段的格式一般为 field name field type field options 一 field options 所有字段共用 1 null 默认为Fals
  • 滤波器拓扑结构:Sallen-key和Multiple Feedback

    在一些关于滤波器设计的地方 总可以看到Sallen key和Multiple Feedback这两个词组 但不清楚什么意思 查了查资料 顺带在此处记录一下 Sallen key 麻省理工学院林肯实验室的R P Sallen and E L
  • Android Studio第一次安装虚拟机时报错Emulator:ERROR: Unknown AVD name[ ], use -list-avds to see valid list.

    安装完虚拟机后点击启动报错 虚拟化已开启 解决办法 1 修改环境变量ANDROID SDK HOME路径指到platforms路径下 例如 D androidSDK platforms 2 重启Android Studio 3 重新安装虚拟
  • 学习笔记:CentOS7安装Docker

    一 检查CentOS 系统的内核版本 Docker 要求 CentOS 系统的内核版本高于 3 10 通过 uname r 命令查看当前的内核版本 二 检查并清除系统残余项 并安装Docker依赖环境 1 卸载Docker 可选 如果之前安
  • 百度新闻资讯类信息爬虫--统计一年内关键词新闻的条数

    背景 通过百度词条搜索 来查找300个关键词 在一年内发布新闻的条数 最终效果实现如下 实现思路 实现思路依然是 先根据多页的url 来找到规律 构建起一页的url def format url url params dict None g
  • [转]信息安全相关理论题(三)

    21 静态分析是运行程序后进行调试 A 对 B 错 您的答案 标准答案 B 22 安卓反编译后会出现 符号字节码表示是匿名内部类 A 对 B 错 您的答案 标准答案 A 23 反编译安卓应用后 一般应该先查看哪一个smali文件的代码 A
  • JAVA反射机制及应用场景

    往往当我们面对一项新的知识时 我们往往需要知道三个方面 它是什么 它能做什么 它比原有知识强在哪里 我们该怎么使用它 当你能够解决这些问题时 便意味着你已经对这项知识入门了 一 是什么 Java Reflaction in Action有这
  • TOGAF9.2第I部分 第2章核心概念

    本章提供的核心概念适用TOGAF标准 2 1 什么是TOGAF标准 TOGAF标准是一个架构框架 它提供了协助接受 生产 使用和维护企业架构的方法和工具 它基于支持最佳实践和可重用的现有架构资产集的迭代过程模型 2 2 TOGAF标准中的架
  • 学习笔记——机器学习(第二章)

    机器学习 第二章 还有很多细节部分 我正在完善和补充 Emmm 若有不足 还请包涵 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  • 致性哈希算法的优化----关于如何保正在环中增加新节点时,命中率不受影响

    背景 09年初 我们做了一个memcached的智能客户端库 业务只要将这个库链上 就能跟memcached服务器通信 并且实现了一致性哈希的分布式算法 后端memcached服务器可以无限制扩展 而且客户端能对memcached做自动故障
  • cmake系列-动态库的生成与链接

    运行系统 Ubuntu20 04 运行环境 python 2 7 17 系统不一样 遇到的问题可能不一样 该方法不一定见效 问题描述 工作中时常需要调用同事写的 so文件作为一些功能的接口 那么如何将cmake文件进行动态库生成和调用呢 实
  • redissonclient类_Redisson入门教程

    Redisson入门 Author RickyDate 2017 04 24 Redisson概述 Redisson是架设在Redis基础上的一个Java驻内存数据网格 In Memory Data Grid 充分的利用了Redis键值数据
  • MySQL数据库学习(保姆级教程)(1.7W字)

    1 初识MySQL JavaEE 企业级Java开发 Web 前端 页面 展示 数据 后台 连接点 连接数据库JDBC 链接前端 控制 控制视图跳转 和给前端传递数据 数据库 存数据 Txt Excel Word 只会写代码 学好数据库 基
  • buuctf web 前5题

    目录 一 极客大挑战 2019 EasySQL 总结 二 极客大挑战 2019 Havefun 总结 三 HCTF 2018 WarmUp 总论 四 ACTF2020 新生赛 Include 总结 五 ACTF2020 新生赛 Exec 总
  • 电脑cpu排名_2019年12月最新CPU天梯图 CPU性能排行榜

    参考国外评测机构PassMark的数据 下面排行榜比较了笔记本和台式电脑CPU的性能 截止更新时间为2019年12月5日 下方为排名前30的CPU天梯图 为方便大家查看更多CPU具体型号的排名和评分 请看天梯图后面的图表 注 电脑端可以使用
  • 投影变换 到 uv坐标 xy/w ---齐次坐标

    float3 vScreenPos In ClipPos xyz vScreenPos In ClipPos w vScreenPos xy 1 f vScreenPos xy 0 5f vScreenPos y 1 f vScreenPo
  • word 插入 高亮代码

    word 插入高亮代码 方法1 直接复制 IDE 中的内容 优 随时随地复制 保留vscode格式 缺 其他IDE的格式可能就不好看了 方法2 代码复制到网站 highlightcode com 高亮后再复制到word 缺 高亮做的不好看
  • 双向BFS搜索和A*算法

    双向BFS适合给出起点和终点 求最短路径的问题 分别从起点和终点扩展 找交点 每次选择待扩展节点少的那个方向进行扩展 一次扩展一层 扩展一个节点的时候 如果节点也在另一个方向的待扩展队列里 找到交点 int doubleBFS vector
  • 1001 害死人不偿命的(3n+1)猜想 (15 分)

    标题 include

随机推荐

  • 【Vue3】学习笔记-reactive响应式

    Vue3 学习笔记 reactive响应式 用ref 设置响应式对象 用reactive 设置响应式对象 总结 用ref 设置响应式对象 JS中设置对象 import ref from vue var user ref username W
  • 2022年美国大学生数学建模-【美赛】A题:Game Theory in Cycling(附获奖论文)

    目录 Summary 1 Introduction 1 1 Problem Background 1 2 Restatement of the Problem 1 3 Our Work 2 Assuptions and Justifific
  • comsol学习中心:几何建模

    创建二维几何 我们打算创建这样的二维模型 这里演示创建 因此不考虑物理场等的设置 创建空白模型 创建的是二维几何 所以在组件中选择天剑二维组件 也可以通过在功能树上右键进行此操作 接着在几何选项卡下找到体素开始构建几何 先添加一个圆形 在功
  • mybaits如何防止SQL注入:mybatis的${}和#{}

    其实这个mybatis的 和 区别和使用 算是很古早很常见的一个基础问题了 先说结论 尽可能使用 不使用 因为 可以防止SQL注入 如果记不清楚 就记一句话或者是口诀 不是所有事都能靠钱能解决 号是货币符号 为什么 可以防止SQL注入 占位
  • Source Insight设置黑色背景

    今天使用Source Insight看C代码 觉得背景白色太亮 觉得应该可以调背景颜色 通过百度 搜索到了CSDN上的相关文章 受益良多 但是文章后面附的style文件下载需30积分 无奈囊中羞涩 只好自己按照文章的说明调颜色 首先将背景调
  • 【基于python实现UI自动化】4.1 selenium发送163邮箱邮件

    python UI自动化 1 0 selenium工具介绍 2 0 selenium环境搭建 3 Selenium的元素定位 3 0 selenium常见8大元素定位 3 1 selenium通过By定位元素 3 2 selenium通过J
  • MySQL出现:ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)问题解决

    本文mysql的安装环境为win7 64位 mysql版本为MySQL5 7 问题描述 在命令行输入 mysql u root p 登录mysql 返回 Can t connect to MySQL server on localhost
  • 【不忘初心】Windows11 22000.168 X64 四合一[纯净精简版][2.77G](2021.8.29)

    此版可正常更新补丁 WIN11全新的UI界面出炉 可以说这一次Windows 11全新升级 无论是从Logo上还是UI界面设计 都有很大的变化 母版来自UUP WIN11 22000 168 为了保证稳定初心的系统全部都是离线精简和优化 非
  • MySQL常用配置详解

    目录 一 MySQL 查看配置信息 二 MySQL 查看服务器当前运行状态的信息 三 MySQL 常用配置详解 1 mysql 使用mysql命令登录数据库时的默认的设置 2 client 客户端默认设置内容 3 mysqld 服务端端配置
  • centos 6.4/redhat 6.4 安装gitlab

    为什么80 的码农都做不了架构师 gt gt gt 一 把所有包升级到最新版本 yum y upgrade 二 安装最新版ruby 2 1 5 步骤http my oschina net duolus blog 348353 三 安装官方给
  • MATLAB对RGB彩色图像进行加马赛克处理

    简单实现MATLAB对RGB彩色图像进行加马赛克处理 为了加深对图像中像素块操作的记忆 利用像素块内均值方式对RGB彩色图像进行马赛克效果的处理 为了能后比较简单得实现 所以采用了n n像素块大小的均值的方式 为了比较简单实现 这里对RGB
  • 简单算法之矩阵运算

    不多说上代码 矩阵对象 class Matrix 矩阵的宽度 private final int width 矩阵的高度 private final int height 矩阵 private final int arr Matrix in
  • 如何创建微信小程序并实现快速变现?

    工作之余做点副业增进一下自己的收入是每个技术从业人员甚至是非技术人员都很喜欢的事情 即所谓的 睡后收入 疫情几年没时间或者说没有精力 随着疫情结束 经济的急速上升 谁不想赶快充实一下自己腰包 微信小程序毋容置疑是比较好的一种方式 做好的微信
  • 语音中的响度,音调与音色的决定因素

    目录 一 先验知识 1 基波与谐波 2 基音与泛音 二 图解泛音的形成原理 生动形象的视频介绍 三 图解泛音决定音色 写在前面 响度由声源的振幅决定 音调由基波的频率决定 音色由泛音决定 一 先验知识 1 基波与谐波 基波是原合成的周期信号
  • 毕业设计-基于机器视觉的室内智能安防车系统 -STM32和 OpenCV

    目录 前言 课题背景和意义 实现技术思路 一 系统整体设计 二 智能安防车硬件系统设计 三 室内安防车自动巡逻机制的实现 四 基于 OpenCV 图像识别的火焰识别 五 分类器设计及软件实现 代码部分 实现效果图样例 最后 前言 大四是整个
  • 主成分分析法确定权重

    在数模中 确定权重方法有很多种 比如主成分分析法 层次分析法 熵权法 相关系数作为权重等 网上很多教程都是用spss计算权重 这里主要讲利用python通过主成分分析法确定权重 主成分分析法概述 主成分分析法是一种线性的降维算法 通过将N维
  • 黑莓QNX选定由延锋伟世通数字仪表项目

    锋影 e mail 174176320 qq com 黑莓有限公司宣布延锋伟世通 全球1级汽车零部件供应商 已经选择该公司的安全认证QNX平台仪器集群1一个数字仪表项目与中国的一个主要的OEM软件 该交易的条款是保密的 黑莓的QNX技术已为
  • istio安装实践

    启动minikube istio的实验环境部署在minikube上 首先启动minikube minikube安装参考上一博客 minikube start vm driver kvm2 extra config controller ma
  • 提高C++性能的编程技术笔记:引用计数+测试代码

    引用计数 reference counting 基本思想是将销毁对象的职责从客户端代码转移到对象本身 对象跟踪记录自身当前被引用的数目 在引用计数达到零时自行销毁 换句话说 对象不再被使用时自行销毁 引用计数和执行速度之间的关系是与上下文紧
  • 基于STM32实现MQTT

    最近一个项目中要用到MQTT或者CoAP 比较了两个的优缺点后 最后选择了MQTT 由于是第一次接触这个协议 在学习中遇到了不少的坑 所以分享出来 第一次写博客 有错勿怪 1 MQTT协议 MQTT Message Queuing Tele