C#使用MQTT(一):MQTT服务端

MQTT(Message Queuing Telemetry Transport)

即时通讯协议,

开发商 IBM

MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。

MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

新建Winform应用程序,将默认的Form1重命名为FormMqttServer

管理Nuget包,输入关键字Mqtt

点击安装

安装完成后示例如图

我们使用MQTTnet.dll,程序集 MQTTnet, Version=4.3.6.1152。应用程序.net framework版本需要4.6.1或者以上

窗体 FormMqttServer 设计如下:

窗体 FormMqttServer设计器代码如下:

文件 FormMqttServer.Designer.cs 


namespace CultureDemo
{partial class FormMqttServer{/// <summary>/// Required designer variable./// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// Clean up any resources being used./// </summary>/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows Form Designer generated code/// <summary>/// Required method for Designer support - do not modify/// the contents of this method with the code editor./// </summary>private void InitializeComponent(){this.lvTopic = new System.Windows.Forms.ListBox();this.lbClients = new System.Windows.Forms.ListBox();this.rtxtMessage = new System.Windows.Forms.RichTextBox();this.label5 = new System.Windows.Forms.Label();this.label4 = new System.Windows.Forms.Label();this.btnStop = new System.Windows.Forms.Button();this.btnStart = new System.Windows.Forms.Button();this.txtPassword = new System.Windows.Forms.TextBox();this.label3 = new System.Windows.Forms.Label();this.txtUsername = new System.Windows.Forms.TextBox();this.label2 = new System.Windows.Forms.Label();this.txtPort = new System.Windows.Forms.TextBox();this.label1 = new System.Windows.Forms.Label();this.txtIP = new System.Windows.Forms.TextBox();this.lb = new System.Windows.Forms.Label();this.dgvTopic = new System.Windows.Forms.DataGridView();this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn();this.Column4 = new System.Windows.Forms.DataGridViewTextBoxColumn();((System.ComponentModel.ISupportInitialize)(this.dgvTopic)).BeginInit();this.SuspendLayout();// // lvTopic// this.lvTopic.FormattingEnabled = true;this.lvTopic.ItemHeight = 12;this.lvTopic.Location = new System.Drawing.Point(686, 35);this.lvTopic.Name = "lvTopic";this.lvTopic.Size = new System.Drawing.Size(300, 136);this.lvTopic.TabIndex = 31;// // lbClients// this.lbClients.FormattingEnabled = true;this.lbClients.ItemHeight = 12;this.lbClients.Location = new System.Drawing.Point(343, 35);this.lbClients.Name = "lbClients";this.lbClients.Size = new System.Drawing.Size(300, 136);this.lbClients.TabIndex = 30;// // rtxtMessage// this.rtxtMessage.Location = new System.Drawing.Point(24, 188);this.rtxtMessage.Name = "rtxtMessage";this.rtxtMessage.Size = new System.Drawing.Size(467, 338);this.rtxtMessage.TabIndex = 29;this.rtxtMessage.Text = "";// // label5// this.label5.AutoSize = true;this.label5.Location = new System.Drawing.Point(684, 17);this.label5.Name = "label5";this.label5.Size = new System.Drawing.Size(53, 12);this.label5.TabIndex = 28;this.label5.Text = "主题列表";// // label4// this.label4.AutoSize = true;this.label4.Location = new System.Drawing.Point(341, 17);this.label4.Name = "label4";this.label4.Size = new System.Drawing.Size(65, 12);this.label4.TabIndex = 27;this.label4.Text = "连接客户端";// // btnStop// this.btnStop.Location = new System.Drawing.Point(129, 148);this.btnStop.Name = "btnStop";this.btnStop.Size = new System.Drawing.Size(75, 23);this.btnStop.TabIndex = 26;this.btnStop.Text = "停止";this.btnStop.UseVisualStyleBackColor = true;this.btnStop.Click += new System.EventHandler(this.btnStop_Click);// // btnStart// this.btnStart.Location = new System.Drawing.Point(32, 148);this.btnStart.Name = "btnStart";this.btnStart.Size = new System.Drawing.Size(75, 23);this.btnStart.TabIndex = 25;this.btnStart.Text = "启动";this.btnStart.UseVisualStyleBackColor = true;this.btnStart.Click += new System.EventHandler(this.btnStart_Click);// // txtPassword// this.txtPassword.Location = new System.Drawing.Point(91, 121);this.txtPassword.Name = "txtPassword";this.txtPassword.Size = new System.Drawing.Size(211, 21);this.txtPassword.TabIndex = 24;this.txtPassword.Text = "1";// // label3// this.label3.AutoSize = true;this.label3.Location = new System.Drawing.Point(44, 124);this.label3.Name = "label3";this.label3.Size = new System.Drawing.Size(29, 12);this.label3.TabIndex = 23;this.label3.Text = "密码";// // txtUsername// this.txtUsername.Location = new System.Drawing.Point(91, 94);this.txtUsername.Name = "txtUsername";this.txtUsername.Size = new System.Drawing.Size(211, 21);this.txtUsername.TabIndex = 22;this.txtUsername.Text = "a";// // label2// this.label2.AutoSize = true;this.label2.Location = new System.Drawing.Point(44, 97);this.label2.Name = "label2";this.label2.Size = new System.Drawing.Size(29, 12);this.label2.TabIndex = 21;this.label2.Text = "账号";// // txtPort// this.txtPort.Location = new System.Drawing.Point(91, 58);this.txtPort.Name = "txtPort";this.txtPort.Size = new System.Drawing.Size(211, 21);this.txtPort.TabIndex = 20;this.txtPort.Text = "12345";// // label1// this.label1.AutoSize = true;this.label1.Location = new System.Drawing.Point(44, 61);this.label1.Name = "label1";this.label1.Size = new System.Drawing.Size(29, 12);this.label1.TabIndex = 19;this.label1.Text = "端口";// // txtIP// this.txtIP.Location = new System.Drawing.Point(91, 16);this.txtIP.Name = "txtIP";this.txtIP.Size = new System.Drawing.Size(211, 21);this.txtIP.TabIndex = 18;this.txtIP.Text = "127.0.0.1";// // lb// this.lb.AutoSize = true;this.lb.Location = new System.Drawing.Point(32, 19);this.lb.Name = "lb";this.lb.Size = new System.Drawing.Size(41, 12);this.lb.TabIndex = 17;this.lb.Text = "IP地址";// // dgvTopic// this.dgvTopic.AllowUserToAddRows = false;this.dgvTopic.AllowUserToDeleteRows = false;this.dgvTopic.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;this.dgvTopic.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {this.Column1,this.Column2,this.Column3,this.Column4});this.dgvTopic.Location = new System.Drawing.Point(522, 188);this.dgvTopic.Name = "dgvTopic";this.dgvTopic.ReadOnly = true;this.dgvTopic.RowTemplate.Height = 23;this.dgvTopic.Size = new System.Drawing.Size(464, 338);this.dgvTopic.TabIndex = 32;// // Column1// this.Column1.HeaderText = "Topic";this.Column1.Name = "Column1";this.Column1.ReadOnly = true;// // Column2// this.Column2.HeaderText = "ClientId";this.Column2.Name = "Column2";this.Column2.ReadOnly = true;// // Column3// this.Column3.HeaderText = "Qos";this.Column3.Name = "Column3";this.Column3.ReadOnly = true;// // Column4// this.Column4.HeaderText = "SessionItems";this.Column4.Name = "Column4";this.Column4.ReadOnly = true;// // FormMqttServer// this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(1013, 538);this.Controls.Add(this.dgvTopic);this.Controls.Add(this.lvTopic);this.Controls.Add(this.lbClients);this.Controls.Add(this.rtxtMessage);this.Controls.Add(this.label5);this.Controls.Add(this.label4);this.Controls.Add(this.btnStop);this.Controls.Add(this.btnStart);this.Controls.Add(this.txtPassword);this.Controls.Add(this.label3);this.Controls.Add(this.txtUsername);this.Controls.Add(this.label2);this.Controls.Add(this.txtPort);this.Controls.Add(this.label1);this.Controls.Add(this.txtIP);this.Controls.Add(this.lb);this.Name = "FormMqttServer";this.Text = "FormMqttServer";this.Load += new System.EventHandler(this.FormMqttServer_Load);((System.ComponentModel.ISupportInitialize)(this.dgvTopic)).EndInit();this.ResumeLayout(false);this.PerformLayout();}#endregionprivate System.Windows.Forms.ListBox lvTopic;private System.Windows.Forms.ListBox lbClients;private System.Windows.Forms.RichTextBox rtxtMessage;private System.Windows.Forms.Label label5;private System.Windows.Forms.Label label4;private System.Windows.Forms.Button btnStop;private System.Windows.Forms.Button btnStart;private System.Windows.Forms.TextBox txtPassword;private System.Windows.Forms.Label label3;private System.Windows.Forms.TextBox txtUsername;private System.Windows.Forms.Label label2;private System.Windows.Forms.TextBox txtPort;private System.Windows.Forms.Label label1;private System.Windows.Forms.TextBox txtIP;private System.Windows.Forms.Label lb;private System.Windows.Forms.DataGridView dgvTopic;private System.Windows.Forms.DataGridViewTextBoxColumn Column1;private System.Windows.Forms.DataGridViewTextBoxColumn Column2;private System.Windows.Forms.DataGridViewTextBoxColumn Column3;private System.Windows.Forms.DataGridViewTextBoxColumn Column4;}
}

窗体FormMqttServer代码如下【MQTT服务端相关代码】

文件FormMqttServer.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;using MQTTnet.Server;
using MQTTnet;
using MQTTnet.Protocol;
using System.Collections;namespace CultureDemo
{public partial class FormMqttServer : Form{private MqttServer server;//mqtt服务器对象public FormMqttServer(){InitializeComponent();rtxtMessage.ReadOnly = true;/** 在MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、可变头(Variable header)、消息体(payload)三部分构成。
固定头(Fixed header):存在于所有MQTT数据包中,表示数据包类型及数据包的分组类标识。
可变头(Variable header):存在于部分MQTT数据包中,数据包类型决定了可变头是否存在及其具体内容。
消息体(Payload):存在于部分MQTT数据包中,表示客户端收到的具体内容。*/}/// <summary>/// 打印相关消息/// </summary>/// <param name="contents"></param>private void DisplayMessage(string contents) {if (!this.IsHandleCreated) {return;}this.BeginInvoke(new Action(() => {if (rtxtMessage.TextLength >= 40960) {rtxtMessage.Clear();}rtxtMessage.AppendText($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}->{contents}\n");rtxtMessage.ScrollToCaret();}));}/// <summary>/// 初始化Mqtt服务并启动服务/// </summary>/// <param name="ip">IPV4地址</param>/// <param name="port">端口:0~65535之间</param>private Task StartMqttServer(string ip, int port){MqttServerOptions mqttServerOptions =new MqttServerOptionsBuilder().WithDefaultEndpoint().WithDefaultEndpointBoundIPAddress(System.Net.IPAddress.Parse(ip)).WithDefaultEndpointPort(port)   .WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(5000)).Build();server = new MqttFactory().CreateMqttServer(mqttServerOptions); // create MQTT service objectserver.ValidatingConnectionAsync += Server_ValidatingConnectionAsync;//验证用户名和密码server.ClientConnectedAsync += Server_ClientConnectedAsync;//绑定客户端连接事件server.ClientDisconnectedAsync += Server_ClientDisconnectedAsync;//绑定客户端断开事件server.ClientSubscribedTopicAsync += Server_ClientSubscribedTopicAsync;//绑定客户端订阅主题事件server.ClientUnsubscribedTopicAsync += Server_ClientUnsubscribedTopicAsync;//绑定客户端退订主题事件server.InterceptingPublishAsync += Server_InterceptingPublishAsync;//消息接收事件server.ClientAcknowledgedPublishPacketAsync += Server_ClientAcknowledgedPublishPacketAsync;server.InterceptingClientEnqueueAsync += Server_InterceptingClientEnqueueAsync;server.ApplicationMessageNotConsumedAsync += Server_ApplicationMessageNotConsumedAsync;server.StartedAsync += Server_StartedAsync;//绑定服务端启动事件server.StoppedAsync += Server_StoppedAsync;//绑定服务端停止事件return server.StartAsync();}private Task Server_ApplicationMessageNotConsumedAsync(ApplicationMessageNotConsumedEventArgs e){try{DisplayMessage($"【MessageNotConsumed】-SenderId:{e.SenderId}-Message:{e.ApplicationMessage.ConvertPayloadToString()}");}catch (Exception ex){DisplayMessage($"Server_ApplicationMessageNotConsumedAsync出现异常:{ex.Message}");}return Task.CompletedTask;}private Task Server_InterceptingClientEnqueueAsync(InterceptingClientApplicationMessageEnqueueEventArgs e){try{DisplayMessage($"【InterceptingClientEnqueue】-SenderId:{e.SenderClientId}-Message:{e.ApplicationMessage.ConvertPayloadToString()}");}catch (Exception ex){DisplayMessage($"Server_InterceptingClientEnqueueAsync出现异常:{ex.Message}");}return Task.CompletedTask;}private Task Server_ClientAcknowledgedPublishPacketAsync(ClientAcknowledgedPublishPacketEventArgs e){try{DisplayMessage($"【ClientAcknowledgedPublishPacket】-SenderId:{e.ClientId}-Message:{Encoding.UTF8.GetString(e.PublishPacket.PayloadSegment.ToArray())}");}catch (Exception ex){DisplayMessage($"Server_ClientAcknowledgedPublishPacketAsync出现异常:{ex.Message}");}return Task.CompletedTask;}/// <summary>/// 消息接收/// </summary>/// <param name="arg"></param>/// <returns></returns>private Task Server_InterceptingPublishAsync(InterceptingPublishEventArgs e){try{string client = e.ClientId;string topic = e.ApplicationMessage.Topic;string contents = e.ApplicationMessage.ConvertPayloadToString();//Encoding.UTF8.GetString(arg.ApplicationMessage.PayloadSegment.ToArray());DisplayMessage($"接收到消息:Client:【{client}】 Topic:【{topic}】 Message:【{contents}】");}catch (Exception ex){DisplayMessage($"Server_InterceptingPublishAsync出现异常:{ex.Message}");}return Task.CompletedTask;}private void FormMqttServer_Load(object sender, EventArgs e){rtxtMessage.Text = @"MQTT服务端关键事件说明:
ClientConnectedAsync-->绑定客户端连接事件
ValidatingConnectionAsync-->验证用户名和密码
ClientSubscribedTopicAsync-->绑定客户端订阅主题事件
InterceptingPublishAsync-->消息接收事件
";}private Task Server_StoppedAsync(EventArgs arg){return Task.Run(new Action(() =>{DisplayMessage($"服务端【{txtIP.Text}:{txtPort.Text}】已停止MQTT");}));}private Task Server_StartedAsync(EventArgs e){return Task.Run(new Action(() =>{DisplayMessage($"服务端【{txtIP.Text}:{txtPort.Text}】已启用MQTT");}));}private Task Server_ClientUnsubscribedTopicAsync(ClientUnsubscribedTopicEventArgs e){return Task.Run(new Action(() =>{lvTopic.Invoke(new Action(() =>{string itemContents = $"【{e.ClientId}】订阅主题【{e.TopicFilter}】";if (lvTopic.Items.Contains(itemContents)){//如果存在该项,就移除lvTopic.Items.Remove(itemContents);}IDictionary collection = e.SessionItems;string[] sessionItemContents = new string[collection.Count];int idx = 0;foreach (object key in collection.Keys){sessionItemContents[idx++] = $"[{key}:{collection[key]}]";}}));DisplayMessage($"客户端【{e.ClientId}】退订主题【{e.TopicFilter}】");}));}private Task Server_ClientSubscribedTopicAsync(ClientSubscribedTopicEventArgs e){return Task.Run(new Action(() =>{lvTopic.Invoke(new Action(() =>{string itemContents = $"【{e.ClientId}】订阅主题【{e.TopicFilter.Topic}】";if (!lvTopic.Items.Contains(itemContents)){//如果不存在该项,就添加lvTopic.Items.Add(itemContents);}IDictionary collection = e.SessionItems;string[] sessionItemContents = new string[collection.Count];int idx = 0;foreach (object key in collection.Keys){sessionItemContents[idx++] = $"[{key}:{collection[key]}]";}dgvTopic.Rows.Add(e.TopicFilter.Topic, e.ClientId, e.TopicFilter.QualityOfServiceLevel, string.Join(",", sessionItemContents));}));DisplayMessage($"客户端【{e.ClientId}】订阅主题【{e.TopicFilter.Topic}】");}));}private Task Server_ClientDisconnectedAsync(ClientDisconnectedEventArgs e){return Task.Run(new Action(() =>{lbClients.BeginInvoke(new Action(() =>{lbClients.Items.Remove(e.ClientId);}));DisplayMessage($"客户端已断开.ClientId:【{e.ClientId}】,Endpoint:【{e.Endpoint}】.ReasonCode:【{e.ReasonCode}】,DisconnectType:【{e.DisconnectType}】");}));}/// <summary>/// 绑定客户端连接事件/// </summary>/// <param name="arg"></param>/// <returns></returns>private Task Server_ClientConnectedAsync(ClientConnectedEventArgs e){return Task.Run(new Action(() =>{lbClients.BeginInvoke(new Action(() =>{lbClients.Items.Add(e.ClientId);}));DisplayMessage($"客户端已连接.ClientId:【{e.ClientId}】,Endpoint:【{e.Endpoint}】");}));}private Task Server_ValidatingConnectionAsync(ValidatingConnectionEventArgs e){return Task.Run(new Action(() =>{string UserName = txtUsername.Text;string Password = txtPassword.Text;if (e.UserName == UserName && e.Password == Password){e.ReasonCode = MqttConnectReasonCode.Success;DisplayMessage($"客户端已验证成功.ClientId:【{e.ClientId}】,Endpoint:【{e.Endpoint}】");}else{e.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;DisplayMessage($"客户端验证失败.ClientId:【{e.ClientId}】,Endpoint:【{e.Endpoint}】");}}));}private async void btnStart_Click(object sender, EventArgs e){await StartMqttServer(txtIP.Text, int.Parse(txtPort.Text));btnStart.Enabled = false;}private async void btnStop_Click(object sender, EventArgs e){await server.StopAsync();btnStart.Enabled = true;}}
}

程序运行如图:

 连接、订阅、发布消息如图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/416193.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图论】Dijkstra算法求最短路

一、Dijkstra算法简介 Dijkstra算法是由河南荷兰计算机科学家狄克斯特拉(Dijkstra)于1959年提出的,因此又叫狄克斯特拉算法。 二、初识Dijkstra算法 在使用Dijkstra算法求最短路时&#xff0c;需要用到三个辅助数组&#xff1a; v i s x vis_x visx​&#xff1a;布尔数组&…

【图灵完备 Turing Complete】游戏经验攻略分享 Part.3 存储器

这一章&#xff0c;前面不难&#xff0c;后面难。 教你别这么连线连出问题。 看结果说话&#xff0c;延迟两个时刻输出。 先不管要求&#xff0c;输出一个稳定的信号&#xff0c;看看之前给了延迟元件正好延迟一刻&#xff0c;然后作为输入和那个稳定的信号做一个逻辑运算改变…

国内可以免费使用的gpt网站【九月持续更新】

GPT Hub 是我最近使用的一款智能文本生成工具平台&#xff0c;它支持多种AI模型&#xff0c;包括最新的GPT-4模型&#xff0c;并且可以在国内网络环境中直接访问。以下是我在使用过程中发现的一些特点&#xff1a; 多功能支持&#xff1a;不仅支持代码生成&#xff0c;还涵盖了…

macos OneNote 2016 for Mac 官方pkg下载地址 - macos 10.15 Catalion 可用Onenote版本官方下载地址

macos 10.15 Catalion 版本的系统已经无法正常从应用商店下载到可用的Onenote 应用,原因是版本不受支持, 而且onenote官方链接的应用商店地址https://apps.apple.com/us/app/microsoft-onenote/id784801555?mt12在中国地区也无法访问, 所以中国地区用户如果想使用onenote应用…

抢先看:2024云栖大会体验攻略

这是一场「AI」奇妙之旅。 2024云栖大会定档 9月19日&#xff01; 期待与你在 杭州云栖小镇 共度一场为期3天的科技盛会 三日主论坛 400分论坛 与并行话题 4万平米 智能科技展区 免费领取云栖大会门票 怎么看、怎么玩、怎么逛 超长干货攻略奉上&#xff0c;请查收 ⬇️…

二开PHP泛目录生成源码 可生成新闻页面和关键词页面——码山侠

PS 本资源提供给大家学习及参考研究借鉴美工之用&#xff0c;请勿用于商业和非法用途&#xff0c;无任何技术支持&#xff01; 下载i5i.net 泛目录可以用来提升网站收录和排名 合理运用目录可以达到快速出词和出权重的效果 程序小 基本的服务器都带的得动 打开i5i.net——…

ROS的Navigation导航系统move_base

Navigation系统和人在使用地图app进行导航的过程类似&#xff0c;接下来让我们看下面的两幅框图&#xff1a; global_planner(全局规划器)从map _server地图服务器获取global_costmap(全局地图数据),然后根 据输入的导航目的地(move_base_simple/goal)生成全局导航路线(intern…

np.c_ 和 np.r_ 的使用

1. np.c_ 的使用 np.c_ 是 NumPy 库中的一个函数&#xff0c;用于沿着第二轴&#xff08;列&#xff09;连接两个或多个数组。这个函数通常用于将两个数组的列合并在一起&#xff0c;而不会改变它们原有的行顺序。np.c_ 是一个非常有用的工具&#xff0c;尤其是在处理需要按列…

Draw.io for Mac/Win:免费且强大的流程图绘制工具

在数字化时代&#xff0c;流程图已成为表达复杂过程和逻辑关系的重要工具。Draw.io&#xff08;现也称为diagrams.net&#xff09;&#xff0c;作为一款免费且功能强大的流程图绘制工具&#xff0c;无论是对于Mac还是Windows用户&#xff0c;都是不可多得的选择。 一、跨平台兼…

基于51单片机的跑马串口调试波形发生器proteus仿真

地址&#xff1a; https://pan.baidu.com/s/1WTjU_hRJ-fLMTT5g1q-NlA 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectro…

python中.之后的圈c、圈v分别代表什么意思?

python中.之后的圈c、圈v分别代表什么意思&#xff1f; Python中&#xff0c;.之后的圈c表示类的实例方法&#xff0c;而圈v表示类的成员变量。 在面向对象编程中&#xff0c;类是一种抽象的数据类型&#xff0c;实例方法是定义在类中的函数&#xff0c;用于操作类的实例变量…

kubeadm方式安装k8s

⼀、安装环境 1. 安装说明 本次以⼆进制⽅式安装⾼可⽤ k8s 1.28.0 版本&#xff0c;但在⽣产环境中&#xff0c;建议使⽤⼩版本⼤于 5 的 Kubernetes 版本&#xff0c;⽐如 1.19.5 以后。 2. 系统环境 3. ⽹络及版本环境 注&#xff1a;宿主机⽹段、Pod ⽹段、Service ⽹段…

Python案例 | 四阶龙格库塔法简介

1.引言 在数值分析中&#xff0c;龙格-库塔法&#xff08;Runge-Kutta methods&#xff09;是用于非线性常微分方程的解的重要的一类隐式或显式迭代法。这些技术由数学家卡尔龙格和马丁威尔海姆库塔于1900年左右发明。 龙格-库塔(Runge-Kutta)方法是一种在工程上应用广泛的高…

59.以太网数据回环实验(2)硬件资源梳理及系统框图

硬件资源梳理介绍&#xff1a; 升腾开发板使用的以太网PHY芯片型号为RTL8211F&#xff0c;是低功耗10-BASE/100-BASE/1000-BASE全双工以太网PHY层芯片&#xff0c;支持 10Mbps、100Mbps 和 1000Mbps以太网通信。I/O 引脚电压可变&#xff0c;符合 IEEE802.3-2005 标准&#xff…

Web3社交新经济,与 SOEX 实现无缝交易的高级安全性

出于充分的理由&#xff0c;安全性是交易中至关重要的考虑因素。每个人都应该确保自己的资金在交易时是安全的。由于 &#xff33;&#xff2f;&#xff25;&#xff38; 充当您与交易所的最佳连接&#xff0c;因此必须强调的是&#xff0c;该系统不会引发任何安全问题。 &a…

wincc 远程和PLC通讯方案

有 5个污水厂 的数据需要集中监控到1个组态软件上,软件是WINCC。每个污水厂监控系统都是独立的&#xff0c;已经投入运行了&#xff0c; 分站也是WINCC 和西门子PLC 。采用巨控远程模块的话&#xff0c;有两种方式&#xff1a;一种是从现场的PLC取数据&#xff0c;一种是从分站…

@DateTimeFormat和@JsonFormat的区别和使用场景

一、区别 DateTimeFormat 用于前端给后端传参时 JsonFormat 用于后端给前端返回时 二、使用场景 2、1 JsonFormat的场景 1、**&#xff08;错误写法&#xff09; **如果参数是实体类&#xff0c;不可以使用DateTimeFormat&#xff0c;这种写法前端传参序列化会报错&#xf…

设计模式-结构型模式-组合模式

1.组合模式的定义 将对象组合成树形结构以表示整个部分的层次结构&#xff0c;组合模式可以让用户统一对待单个对象和对象的组合&#xff1b;其更像是一种数据结构和算法的抽象&#xff0c;其中数据可以表示成树这种数据结构&#xff0c;业务需求可以通过在树上的递归遍历算法来…

论文速读|BiGym:一款基于演示的移动双手操作机器人基准

项目地址&#xff1a;BiGym: A Demo-Driven Mobile Bi-Manual Manipulation Benchmark BiGym 是一个针对移动双手操作的机器人学习基准&#xff0c;包含 40 个在家庭环境中进行的任务&#xff0c;如简单的目标接近到复杂的厨房清洁。这些任务涵盖了从固定的目标接近到需要与各种…

儿童耳勺需要买吗?真实测评赞誉有加的五大品牌

作为个护师&#xff0c;经常会碰到有家长问我需不需要买儿童耳勺&#xff0c;我每次的回答都必须是要的。因为传统耳勺由于不可视的原因&#xff0c;家长无法看清儿童狭窄的耳道&#xff0c;极容易刮伤儿童耳道。但是需要买哪种儿童耳勺&#xff1f; 这里可以跟大家分享一款神器…