XZJ.Communication 1.0.0

dotnet add package XZJ.Communication --version 1.0.0
                    
NuGet\Install-Package XZJ.Communication -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="XZJ.Communication" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="XZJ.Communication" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="XZJ.Communication" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add XZJ.Communication --version 1.0.0
                    
#r "nuget: XZJ.Communication, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package XZJ.Communication@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=XZJ.Communication&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=XZJ.Communication&version=1.0.0
                    
Install as a Cake Tool

一个简单的通信库

  • 简单的 TcpServer 、TcpClient 、Modbus 通信库

  • TcpServer、TcpClient 用于短报文 数据通信。

  • Modbus 基于NMODBUS 开发,使其更贴近开发。

  • 问题反馈邮箱 330532631@qq.com

1、MODBUS

  • 寄存器、离散状态、输入寄存器、线圈都被定义成一个 MBUnit 即‘单元' 通过XML 文件配置。也可以通过数据库 UI 界面配置,不过这需要你自己去扩展了。
  • 默认文件名称是 Modbus.xml 文件属性 复制到输出目录:始终复制或 较新则复制,生成操作:嵌入的资源
  • 以下是 XML 结构,请详细阅读 了解关联关系。
  • 目前TCP RTU 互相透传并未实现。
<?xml version="1.0" encoding="utf-8" ?>


<Modbus PollingInterval="1000">
	
	
	<SlaveDevice  Name="S71214" Enable="true"  ConnectType="TCP" Description="这是一个PLC 设备" Endianness="LittleEndian" ReconnectInterval="5000">
		
		
		<TCP Address="127.0.0.1"  Port="502"        IsTcpToRtu="false"/>
		
		
		<RTU ComName="Com1"       BaudRate="9600"   DataBits="8" Parity="1" StopBits="None" IsRtuToTcp="false"/>
		
		
		<Slave SlaveId="1" Name="TestSlave" Description="">
			
			
			<Region Name="region1" RegionType="HoldingRegister" StartAddress="0" EndAddress="10" IsPolling="true" PollingTimeInterval="10000">
				
				
				<Unit Name="HoldingRegister1"	   Description="测试寄存器1"   DataType="Float"  Position="0" />
				<Unit Name="HoldingRegister2"	   Description="测试寄存器2"   DataType="Int16"  Position="2" />
			</Region>
			<Region Name="region2" RegionType="HoldingRegister" StartAddress="10" EndAddress="20" IsPolling="true" PollingTimeInterval="10000">
				<Unit Name="HoldingRegister7"	   Description="测试寄存器7"   DataType="DInt"   Position="0" />
				<Unit Name="HoldingRegister8"	   Description="测试寄存器8"   DataType="Int16"  Position="2" />
			</Region>
			<Region Name="region3" RegionType="HoldingRegister" StartAddress="40" EndAddress="50" IsPolling="true" PollingTimeInterval="10000">
				<Unit Name="HoldingRegister21"	   Description="测试寄存器21"  DataType="Int16"  Position="0" />
				<Unit Name="HoldingRegiste21"	   Description="测试寄存器22"  DataType="Int16"  Position="2" />
			</Region>


			
			<Unit  Name="Test1"	       Description="通道1进平均温度"          Register="HoldingRegister"	 DataType="Int16"  Position="51"  IsPolling="true" PollingTimeInterval="3000"/>
			<Unit  Name="Test2"	       Description="通道1进最高温度"          Register="HoldingRegister"	 DataType="Int16"  Position="61"  IsPolling="true" PollingTimeInterval="3000"/>
			<Unit  Name="Tes3"	       Description="通道1进超过特定温度面积"  Register="HoldingRegister"	 DataType="Int16"  Position="71"  IsPolling="true" PollingTimeInterval="3000"/>

		</Slave>
	</SlaveDevice>

	<SlaveDevice  Name="S71215" Enable="true"  ConnectType="TCP" Description="这是一个PLC 设备" Endianness="LittleEndian" ReconnectInterval="5000" PollingInterval="65000">
		<TCP Address="127.0.0.1"  Port="503"        IsTcpToRtu="false"/>
		<RTU ComName="Com1"       BaudRate="9600"   DataBits="8" Parity="1" StopBits="None" IsTcpToRtu="false"/>
		<Slave SlaveId="1" Name="TestSlave" Description="">	
			<Region Name="region1" RegionType="CoilStatus" StartAddress="0" EndAddress="10" IsPolling="true" PollingTimeInterval="1000">
				<- 线圈状态默认Bool 无需申明 ->
				<Unit Name="CoilStatus1"	   Description="线圈1"  Register="CoilStatus"   Position="0" />
				<Unit Name="CoilStatus2"	   Description="线圈2"  Register="CoilStatus"   Position="1" />
				<Unit Name="CoilStatus3"	   Description="线圈3"  Register="CoilStatus"   Position="2" />
				<Unit Name="CoilStatus4"	   Description="线圈4"  Register="CoilStatus"   Position="3" />
				<Unit Name="CoilStatus5"	   Description="线圈5"  Register="CoilStatus"   Position="4" />
			</Region>
		</Slave>
	</SlaveDevice>
</Modbus>

数据类型

  • 其中几组数据类型,申明哪个都是一样的效果
  • Int16 与 Short
  • Int32 与 DInt
  • Float 与 Real
public enum DataType
{
    Bool,
    /// <summary>16位有符号整数(Int16/short)</summary>
    Int16,
    /// <summary>32位有符号整数(Int32/int)</summary>
    Int32,
    /// <summary>32位浮点数(Float/single)</summary>
    Float,
    /// <summary>16位无符号整数(UInt16/ushort)</summary>
    UInt,
    /// <summary>32位有符号整数(Int32/int)</summary>
    DInt,
    /// <summary>32位浮点数(Float/single)</summary>
    Real,
    /// <summary>16位有符号整数(Int16/short)</summary>
    Short,
    /// <summary>字符串(UTF8/ASCII)</summary>
    String
}

使用方法 基于以上XML 配置为例

1.初始化 MBService 并启动服务,服务会扫描名称为 Modbus.xml 文件,并加载。

    //使用默认文件名和路径 AppDomain.CurrentDomain.BaseDirectory + "Modbus.xml"
    IServer server = new MBService();
            server.StartAsync();

    //使用自定义文件名和路径 
    IServer server = new MBService(new XMLUnitConfig(path:"D:\\CustomModbus.xml"));
            server.StartAsync();

2.获取设备、从站、区域、单元

  • 获取从站设备
//获取设备
var s71214 = "S71214".GetMBMasterClient();
//获取从站集合
var slaves = s71214.Slaves;
  • 获取从站
//获取从站
var s71214Slave = "S71214.1".GetMBSlave();
//获取从站区域集合
var regions = s71214Slave.Regions;
//获取从站零散单元集合
var units = s71214Slave.Units;
  • 获取区域
//获取区域
var s71214SlaveRegion = "S71214.1.region1".GetMBRegion();
//获取区域单元集合
var units = s71214SlaveRegion.Units;
  • 获取区域单元
var s71214SlaveRegionUnit = "S71214.1.region1.HoldingRegister1".GetMBRegionUnit();
  • 获取从站零散单元
var s71214SlaveUnit = "S71214.1.Test1".GetMBSlaveUnit();

3.代码获取值

//如果我们想读取 设备为 S71214 从站 1 区域为 region1 的数据
//第一种形式 获取区域
var region1 = "S71214.1.region1".GetMBRegion();                   
//读取单元
MBUnit mbUnit1 = region1["HoldingRegister1"];//直接 string floatValue = region1["HoldingRegister1"].Value 也是可以的
//读取单元值 
string floatValue = mbUnit1.Value;
//读取出来的值 都是字符串形式,需要自己转换
float fv=float.Parse(floatValue);

//第二种形式 设备名称+从站ID+区域名称+单元名称
string floatValue = "S71214.1.region1.HoldingRegister1".GetMBRegionUnit().Value;

4.代码写值,参照以上代码

  • 第一种方式 获取单元对象,然后再赋值
//获取单元
MBUnit mbUnit1 = region1["HoldingRegister1"];
//写单元值 
mbUnit1.Value="45.6";
  • 第二种方式 区域+单元名称索引
region1["HoldingRegister1"].Value="45.6;
  • 第三种方式 设备名称+从站ID+区域名称+单元名称
"S71214.1.region1.HoldingRegister1".GetMBRegionUnit().Value = "45.6";

5. 事件绑定

  • 绑定更新数据 触发事件。当从站有更新数据,上位机获取到新的数据时触发
//获取单元
MBUnit mbUnit1 = region1["HoldingRegister1"];
//绑定事件,当有新数据且不重复时触发
mbUnit1.EventUnitValueUpdated += Unit_EventUnitValueUpdated;
//绑定方法
private void Unit_EventUnitValueUpdated(MBUnit obj)
{
    //从站更新的数据
    Console.WriteLine(obj.Value);
}
  • 绑定写入成功 触发事件 当上位机写入设备成功时触发
//获取单元
MBUnit mbUnit1 = region1["HoldingRegister1"];
//绑定事件,当写值成功时触发
mbUnit1.EventWriteSuccess += Dd_EventWriteSuccess;
//触发方法
private void Dd_EventWriteSuccess()
{
    Console.WriteLine(" mbUnit1  写成功");
}

6. WPF 数据绑定

  • C# 后台代码
public MainWindow()
{
    InitializeComponent();
    //初始MB服务
    IServer server = new MBService();
    //启动服务
    server.StartAsync();
    //获取区域 S71214 设备 从站为 1 区域为 region1的数据
    var region= "S71214.1.region1".GetMBRegion();
    //绑定数据上下文
    this.DataContext = region;     
}
  • XML 绑定代码
<Grid>
    <TextBox Text="{Binding Units[HoldingRegister1].Value}" FontSize="20" Height="40" Foreground="Red"/>
    <Button Height="40" VerticalAlignment="Top" Foreground="Red" Click="Button_Click"/>
</Grid>

7. 动态增删

  • 以下为演示代码,验证是可以动态增删的
	//获取区域
	var region = "S71214.1.region1".GetMBRegion();
	//获取从站
	var slave="S71214.1".GetMBSlave();
	//移除区域
	MBClientManage.Instance.RemoveRegion(slave, region);
	Console.WriteLine("区域被移除了");
	//观察结果 ,是不是真的移除了
	Console.ReadLine();
	//重新添加区域
	MBClientManage.Instance.AddRegion(slave, region);
	Console.WriteLine("区域被添加了");
	//观察结果,是不是真的添加了
	Console.ReadLine();
	//移除设备
	var client = MBClientManage.Instance.RemoveClient("S71214");
	Console.WriteLine("设备被移除了");
	//释放连接
	client.Disconnect();
	//观察结果是不是真的移除了设备
	Console.ReadLine();
	//重新添加设备
	var addClient = MBClientManage.Instance.AddClient(client);
	Console.WriteLine("设备被添加了");
	//设置使能
	addClient.Enable = true;
	//启动设备
	addClient.StartAsync();
	//观窕结果 是不是真的重新添加了
	Console.ReadLine();
	Console.WriteLine();

2. TCPServer

	//创建TCP服务器
	TCPServer tCPServer = new TCPServer();
	//服务启动成功触发事件
	tCPServer.EventServerStart += TCPServer_EventServerStart;
	//服务启动失败触发事件
	tCPServer.EventServerStartFail += TCPServer_EventServerStartFail;
	//新客户端连接触发事件
	tCPServer.EventClientConnected += TCPServer_EventClientConnected;
	//客户端失去连接触发事件
	tCPServer.EventClientDisconnected += TCPServer_EventClientDisconnected;
	//客户端接收到新数据触发事件
	tCPServer.EventDataReceived += TCPServer_EventDataReceived;
	//服务器启动
	tCPServer.StartAsync();

3. TCPClient

	//创建客户端
	TCPClient tCPClient = new TCPClient("127.0.0.1", 3000);
	//连接服务器成功触发事件
	tCPClient.EventConnectSuccess += TCPClient_EventConnectSuccess;
	//连接服务器失败触发事件
	tCPClient.EventConnectFail += TCPClient_EventConnectFail;
	//断开连接触发事件
	tCPClient.EventDisconnect += TCPClient_EventDisconnect;
	//接收到新数据触发事件
	tCPClient.EventDataReceived += TCPClient_EventDataReceived;
	//自动重连成功触发事件
	tCPClient.EventReconnectSuccess += TCPClient_EventReconnectSuccess;
	//心跳数据发送失败触发事件
	tCPClient.EventHeartbeatFail += TCPClient_EventHeartbeatFail;

	//连接超时设置
	tCPClient.ConnectTimeoutMs = 10000;
	//数据编码设置
	tCPClient.DataEncoding = "UTF-8";
	//自动重连设置 默认为 true
	tCPClient.AutoReconnect = true;
	//重连次数据设置,-1 无限重连
	tCPClient.MaxReconnectTimes = -1;
	//重连间隔设置
	tCPClient.ReconnectIntervalMs = 5000;
	//心跳使能设置
	tCPClient.EnableHeartbeat = true;
	//心跳间隔设置
	tCPClient.HeartbeatIntervalMs = 5000;
	//心跳数据设置
	tCPClient.HeartbeatData = "这是一个心跳数据";
	//连接服务器
	_ = tCPClient.ConnectServer();

	//向服务器发送数据
	_ = tCPClient.SendDataAsync("床前明月光");
Console.WriteLine();
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Framework net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 299 12/16/2025