引言
在物联网迅速发展的今天,设备间的通信协议扮演着至关重要的角色。它们是不同设备、系统之间实现数据交换的桥梁。本文将详细介绍三种在物联网领域广泛应用的通讯协议------MQTT、Modbus和OPC,包括它们的基础概念、特点及在C#中的实现方法。
一、MQTT协议
1. 基础概念
MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅消息传输协议,专为物联网设备通信设计 6 。它基于发布/订阅(Pub/Sub)模式,包含三个核心角色:
-
发布者(Publisher) :发送消息的设备或应用
-
代理(Broker) :消息的中转中心,负责接收和分发消息
-
订阅者(Subscriber) :接收特定主题消息的设备或应用 MQTT的轻量级特性体现在:
-
最小化报文头仅2字节,最小报文仅2字节
-
低带宽消耗,1KB消息传输开销小于5%
-
支持QoS(服务质量)分级保障:
-
QoS 0:至多一次(Fire and Forget)
-
QoS 1:至少一次(Acknowledged Delivery)
-
QoS 2:精确一次(Assured Delivery)
-
2. C#实现示例
在C#中,我们可以使用MQTTnet库来实现MQTT通信。首先通过NuGet安装:
Install-Package MQTTnet
以下是一个简单的MQTT客户端实现:
using MQTTnet;
using MQTTnet.Client;
using System.Text;
class MQTTClientExample
{
private static async Task Main(string[] args)
{
// 创建MQTT客户端
var factory = new MqttFactory();
var client = factory.CreateMqttClient();
// 配置连接选项
var options = new MqttClientOptionsBuilder
()
.WithTcpServer("broker.hivemq.com",
1883) // 连接到公共MQTT代理
.WithClientId("CsharpClient")
.WithCleanSession()
.Build();
// 连接事件处理
client.ConnectedAsync += async (e) =>
{
Console.WriteLine("已连接到MQTT代理");
// 订阅主题
await client.SubscribeAsync("iot/
sensors");
Console.WriteLine("已订阅主题: iot/
sensors");
};
// 消息接收事件处理
client.ApplicationMessageReceivedAsync +=
(e)
=>
{
Console.WriteLine($"收到消息: 主题=
{e.ApplicationMessage.Topic}, 内容
={Encoding.UTF8.GetString(e.
ApplicationMessage.Payload)}");
return Task.CompletedTask;
};
// 连接到MQTT代理
await client.ConnectAsync(options);
// 发布消息
var message = new
MqttApplicationMessageBuilder()
.WithTopic("iot/commands")
.WithPayload("
{\"action\":\"read_sensors\"}")
.WithQualityOfServiceLevel
(MqttQualityOfServiceLevel.
AtLeastOnce)
.Build();
await client.PublishAsync(message);
Console.WriteLine("已发布消息到主题: iot/
commands");
// 保持程序运行
Console.ReadLine();
await client.DisconnectAsync();
}
}
二、Modbus协议
1. 基础概念
Modbus是一种应用广泛的工业通信协议,由Modicon公司(现施耐德电气)于1979年开发 2 。它是一种主从式协议,支持以下几种主要变体:
-
Modbus RTU :基于串口(RS-232/RS-485)的二进制格式
-
Modbus ASCII :基于串口的ASCII字符格式
-
Modbus TCP :基于以太网的TCP/IP协议 Modbus协议通过寄存器地址进行数据访问,主要包含:
-
线圈寄存器(Coils):用于开关量输出
-
离散输入寄存器(Discrete Inputs):用于开关量输入
-
保持寄存器(Holding Registers):用于模拟量输出和数据存储
-
输入寄存器(Input Registers):用于模拟量输入
2. C#实现示例
在C#中,我们可以使用NModbus库来实现Modbus通信。首先通过NuGet安装:
Install-Package NModbus
以下是一个Modbus TCP客户端实现示例:
using Modbus.Data;
using Modbus.Device;
using Modbus.Utility;
using System.Net.Sockets;
class ModbusTcpClientExample
{
private static void Main(string[] args)
{
// 连接到Modbus TCP服务器
TcpClient client = new TcpClient("127.0.0.
1", 502);
IModbusMaster master = ModbusIpMaster.
CreateIp(client);
// 读取保持寄存器(地址100-103)
ushort startAddress = 100;
ushort numRegisters = 4;
ushort[] registers = master.
ReadHoldingRegisters(1, startAddress,
numRegisters);
Console.WriteLine("读取保持寄存器结果:");
for (int i = 0; i < registers.Length; i++)
{
Console.WriteLine($"寄存器
{startAddress + i}: {registers[i]}");
}
// 写入单个保持寄存器
ushort writeAddress = 100;
ushort writeValue = 1234;
master.WriteSingleRegister(1,
writeAddress, writeValue);
Console.WriteLine($"已写入寄存器
{writeAddress}: {writeValue}");
// 写入多个保持寄存器
ushort[] writeValues = { 5678, 9012 };
master.WriteMultipleRegisters(1, 101,
writeValues);
Console.WriteLine("已写入多个寄存器");
client.Close();
}
}
三、OPC协议
1. 基础概念
OPC(OLE for Process Control)是工业自动化领域的通信标准,旨在实现不同厂商设备和系统之间的互操作性 3 。目前主要有两个版本:
-
OPC DA(Data Access) :基于微软COM/DCOM技术,适用于Windows平台
-
OPC UA(Unified Architecture) :平台无关、厂商无关的统一架构,支持跨平台通信 OPC UA的主要特点:
-
平台无关:支持Windows、Linux、macOS等多种操作系统
-
安全可靠:提供端到端的加密和认证
-
信息建模:支持复杂的数据结构和语义
-
可扩展性:支持分布式系统和大规模部署
2. C#实现示例
对于OPC UA,我们可以使用OPC Foundation提供的OPC UA .NET Standard库。首先通过NuGet安装:
Install-Package Opc.Ua.Client
以下是一个简单的OPC UA客户端实现:
using Opc.Ua;
using Opc.Ua.Client;
using System;
using System.Collections.Generic;
class OpcUaClientExample
{
private static void Main(string[] args)
{
// 创建应用程序配置
ApplicationConfiguration config = new
ApplicationConfiguration()
{
ApplicationName = "CsharpOpcUaClient",
ApplicationType = ApplicationType.
Client,
SecurityConfiguration = new
SecurityConfiguration()
{
ApplicationCertificate = new
CertificateIdentifier() {
StoreType = "Directory",
StorePath =
@"%CommonApplicationData%\OPC
Foundation\CertificateStores\Machi
neDefault", SubjectName =
"CsharpOpcUaClient" },
TrustedIssuerCertificates = new
CertificateTrustList { StoreType
= "Directory", StorePath =
@"%CommonApplicationData%\OPC
Foundation\CertificateStores\UA
Certificate Authorities" },
TrustedPeerCertificates = new
CertificateTrustList { StoreType
= "Directory", StorePath =
@"%CommonApplicationData%\OPC
Foundation\CertificateStores\UA
Applications" },
RejectedCertificateStore = new
CertificateTrustList { StoreType
= "Directory", StorePath =
@"%CommonApplicationData%\OPC
Foundation\CertificateStores\Rejec
tedCertificates" }
}
};
config.Validate(ApplicationType.Client).
GetAwaiter().GetResult();
// 创建会话
string endpointUrl = "opc.tcp://
localhost:4840/";
EndpointDescription endpoint =
CoreClientUtils.SelectEndpoint
(endpointUrl, useSecurity: false);
ConfiguredEndpoint configuredEndpoint =
new ConfiguredEndpoint(null, endpoint,
EndpointConfiguration.Create(config));
Session session = Session.Create(config,
configuredEndpoint, false,
"CsharpOpcUaClient", 60000, new
UserIdentity(), null).GetAwaiter().
GetResult();
Console.WriteLine("已连接到OPC UA服务器");
// 读取节点值
NodeId nodeId = new NodeId("ns=2;
s=Temperature");
DataValue value = session.ReadValue
(nodeId);
Console.WriteLine($"读取节点值: {value.
Value}