2014-08-01 update 6 Add comment
This commit is contained in:
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace ModBus.Net
|
namespace ModBus.Net
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数据单元翻译器
|
||||||
|
/// </summary>
|
||||||
public abstract class AddressTranslator
|
public abstract class AddressTranslator
|
||||||
{
|
{
|
||||||
protected static AddressTranslator _instance;
|
protected static AddressTranslator _instance;
|
||||||
@@ -10,6 +13,9 @@ namespace ModBus.Net
|
|||||||
public abstract ushort AddressTranslate(string address);
|
public abstract ushort AddressTranslate(string address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// NA200H数据单元翻译器
|
||||||
|
/// </summary>
|
||||||
public class AddressTranslatorNA200H : AddressTranslator
|
public class AddressTranslatorNA200H : AddressTranslator
|
||||||
{
|
{
|
||||||
private AddressTranslatorNA200H()
|
private AddressTranslatorNA200H()
|
||||||
|
|||||||
@@ -4,10 +4,13 @@ using System.Reflection;
|
|||||||
|
|
||||||
namespace ModBus.Net
|
namespace ModBus.Net
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 基本协议
|
||||||
|
/// </summary>
|
||||||
public abstract class BaseProtocal
|
public abstract class BaseProtocal
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 发送数据
|
/// 发送数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="content">需要发送的数据</param>
|
/// <param name="content">需要发送的数据</param>
|
||||||
/// <returns>数据是否正确接收</returns>
|
/// <returns>数据是否正确接收</returns>
|
||||||
@@ -18,6 +21,11 @@ namespace ModBus.Net
|
|||||||
Protocals = new Dictionary<string, ProtocalUnit>();
|
Protocals = new Dictionary<string, ProtocalUnit>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 协议索引器,这是一个懒加载协议,当字典中不存在协议时自动加载协议,否则调用已经加载的协议
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="protocalName">协议的类的名称</param>
|
||||||
|
/// <returns></returns>
|
||||||
public ProtocalUnit this[string protocalName]
|
public ProtocalUnit this[string protocalName]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -26,6 +34,7 @@ namespace ModBus.Net
|
|||||||
{
|
{
|
||||||
return Protocals[protocalName];
|
return Protocals[protocalName];
|
||||||
}
|
}
|
||||||
|
//自动寻找存在的协议并将其加载
|
||||||
var protocalUnit =
|
var protocalUnit =
|
||||||
Assembly.Load("ModBus.Net").CreateInstance("ModBus.Net." + protocalName) as ProtocalUnit;
|
Assembly.Load("ModBus.Net").CreateInstance("ModBus.Net." + protocalName) as ProtocalUnit;
|
||||||
if (protocalUnit == null) throw new InvalidCastException("没有相应的协议内容");
|
if (protocalUnit == null) throw new InvalidCastException("没有相应的协议内容");
|
||||||
@@ -36,24 +45,29 @@ namespace ModBus.Net
|
|||||||
|
|
||||||
protected Dictionary<string, ProtocalUnit> Protocals { get; private set; }
|
protected Dictionary<string, ProtocalUnit> Protocals { get; private set; }
|
||||||
|
|
||||||
public void Register(ProtocalUnit linkProtocal)
|
protected void Register(ProtocalUnit linkProtocal)
|
||||||
{
|
{
|
||||||
if (linkProtocal == null) return;
|
if (linkProtocal == null) return;
|
||||||
Protocals.Add(linkProtocal.GetType().Name, linkProtocal);
|
Protocals.Add(linkProtocal.GetType().Name, linkProtocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送协议内容并接收,一般方法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public virtual byte[] SendReceive(params object[] content)
|
public virtual byte[] SendReceive(params object[] content)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
return _protocalLinker.SendReceive(ProtocalUnit.TranslateContent(content));
|
return _protocalLinker.SendReceive(ProtocalUnit.TranslateContent(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual OutputStruct SendReceive(ProtocalUnit unit, params object[] content)
|
/// <summary>
|
||||||
{
|
/// 发送协议,通过传入需要使用的协议内容和输入结构
|
||||||
int t = 0;
|
/// </summary>
|
||||||
return unit.Unformat(_protocalLinker.SendReceive(unit.Format(content)), ref t);
|
/// <param name="unit"></param>
|
||||||
}
|
/// <param name="content"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public virtual OutputStruct SendReceive(ProtocalUnit unit, InputStruct content)
|
public virtual OutputStruct SendReceive(ProtocalUnit unit, InputStruct content)
|
||||||
{
|
{
|
||||||
int t = 0;
|
int t = 0;
|
||||||
@@ -61,14 +75,22 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 接收数据
|
/// 仅发送数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>接收到的数据</returns>
|
/// <param name="unit"></param>
|
||||||
|
/// <param name="content"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public virtual bool SendOnly(ProtocalUnit unit, params object[] content)
|
public virtual bool SendOnly(ProtocalUnit unit, params object[] content)
|
||||||
{
|
{
|
||||||
return _protocalLinker.SendOnly(unit.Format(content));
|
return _protocalLinker.SendOnly(unit.Format(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 仅发送数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="unit"></param>
|
||||||
|
/// <param name="content"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public virtual bool SendOnly(ProtocalUnit unit, InputStruct content)
|
public virtual bool SendOnly(ProtocalUnit unit, InputStruct content)
|
||||||
{
|
{
|
||||||
return _protocalLinker.SendOnly(unit.Format(content));
|
return _protocalLinker.SendOnly(unit.Format(content));
|
||||||
|
|||||||
@@ -1,11 +1,30 @@
|
|||||||
namespace ModBus.Net
|
namespace ModBus.Net
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 协议转换的接口
|
||||||
|
/// </summary>
|
||||||
public interface IProtocalFormatting
|
public interface IProtocalFormatting
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 从输入结构格式化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <returns></returns>
|
||||||
byte[] Format(InputStruct message);
|
byte[] Format(InputStruct message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从对象的参数数组格式化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <returns></returns>
|
||||||
byte[] Format(params object[] message);
|
byte[] Format(params object[] message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把仪器返回的内容填充到输出结构中
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messageBytes"></param>
|
||||||
|
/// <param name="pos"></param>
|
||||||
|
/// <returns></returns>
|
||||||
OutputStruct Unformat(byte[] messageBytes, ref int pos);
|
OutputStruct Unformat(byte[] messageBytes, ref int pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,9 @@
|
|||||||
<DependentUpon>ConfigurationManager.resx</DependentUpon>
|
<DependentUpon>ConfigurationManager.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="IProtocalFormatting.cs" />
|
<Compile Include="IProtocalFormatting.cs" />
|
||||||
|
<Compile Include="ModbusTcpProtocalLinker.cs" />
|
||||||
<Compile Include="ProtocalLinker.cs" />
|
<Compile Include="ProtocalLinker.cs" />
|
||||||
|
<Compile Include="ProtocalLinkerBytesExtend.cs" />
|
||||||
<Compile Include="ProtocalUnit.cs" />
|
<Compile Include="ProtocalUnit.cs" />
|
||||||
<Compile Include="ModbusProtocal.cs" />
|
<Compile Include="ModbusProtocal.cs" />
|
||||||
<Compile Include="ModbusTCPProtocal.cs" />
|
<Compile Include="ModbusTCPProtocal.cs" />
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ namespace ModBus.Net
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读线圈状态
|
||||||
|
/// </summary>
|
||||||
public class ReadCoilStatusModbusProtocal : ProtocalUnit
|
public class ReadCoilStatusModbusProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
@@ -91,6 +94,9 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读输入状态协
|
||||||
|
/// </summary>
|
||||||
public class ReadInputStatusModbusProtocal : ProtocalUnit
|
public class ReadInputStatusModbusProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
@@ -161,6 +167,9 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读保持型寄存器
|
||||||
|
/// </summary>
|
||||||
public class ReadHoldRegisterModbusProtocal : ProtocalUnit
|
public class ReadHoldRegisterModbusProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
@@ -224,6 +233,9 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读输入型寄存器
|
||||||
|
/// </summary>
|
||||||
public class ReadInputRegisterModbusProtocal : ProtocalUnit
|
public class ReadInputRegisterModbusProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
@@ -347,6 +359,9 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读单个线圈状态
|
||||||
|
/// </summary>
|
||||||
public class WriteOneCoilModbusProtocal : ProtocalUnit
|
public class WriteOneCoilModbusProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
@@ -406,6 +421,9 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 写单个寄存器状态
|
||||||
|
/// </summary>
|
||||||
public class WriteOneRegisterModbusProtocal : ProtocalUnit
|
public class WriteOneRegisterModbusProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
@@ -463,6 +481,9 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 写多个线圈状态
|
||||||
|
/// </summary>
|
||||||
public class WriteMultiCoilModbusProtocal : ProtocalUnit
|
public class WriteMultiCoilModbusProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
@@ -537,6 +558,9 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 写多个寄存器状态
|
||||||
|
/// </summary>
|
||||||
public class WriteMultiRegisterModbusProtocal : ProtocalUnit
|
public class WriteMultiRegisterModbusProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
@@ -602,6 +626,9 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读系统时间
|
||||||
|
/// </summary>
|
||||||
public class GetSystemTimeModbusProtocal : ProtocalUnit
|
public class GetSystemTimeModbusProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
@@ -668,6 +695,9 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 写系统时间
|
||||||
|
/// </summary>
|
||||||
public class SetSystemTimeModbusProtocal : ProtocalUnit
|
public class SetSystemTimeModbusProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
|
|||||||
@@ -2,11 +2,15 @@
|
|||||||
|
|
||||||
namespace ModBus.Net
|
namespace ModBus.Net
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Modbus/Tcp协议
|
||||||
|
/// </summary>
|
||||||
public class ModbusTcpProtocal : ModbusProtocal
|
public class ModbusTcpProtocal : ModbusProtocal
|
||||||
{
|
{
|
||||||
|
//将连接器设置为Tcp连接器
|
||||||
public ModbusTcpProtocal()
|
public ModbusTcpProtocal()
|
||||||
{
|
{
|
||||||
_protocalLinker = new TcpProtocalLinker();
|
_protocalLinker = new ModbusTcpProtocalLinker();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
20
NA200H/ModBus.Net/ModbusTcpProtocalLinker.cs
Normal file
20
NA200H/ModBus.Net/ModbusTcpProtocalLinker.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ModBus.Net
|
||||||
|
{
|
||||||
|
class ModbusTcpProtocalLinker : TcpProtocalLinker
|
||||||
|
{
|
||||||
|
public override bool CheckRight(byte[] content)
|
||||||
|
{
|
||||||
|
if (content[1] > 127)
|
||||||
|
{
|
||||||
|
throw new ModbusProtocalErrorException(content[2]);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,22 +2,54 @@
|
|||||||
|
|
||||||
namespace ModBus.Net
|
namespace ModBus.Net
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 基本的协议连接器
|
||||||
|
/// </summary>
|
||||||
public abstract class ProtocalLinker
|
public abstract class ProtocalLinker
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 发送并接收数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">发送协议的内容</param>
|
||||||
|
/// <returns>接收协议的内容</returns>
|
||||||
public abstract byte[] SendReceive(byte[] content);
|
public abstract byte[] SendReceive(byte[] content);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 仅发送数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">发送协议的内容</param>
|
||||||
|
/// <returns>协议是否正确发送</returns>
|
||||||
public abstract bool SendOnly(byte[] content);
|
public abstract bool SendOnly(byte[] content);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查接收的数据是否正确
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">接收协议的内容</param>
|
||||||
|
/// <returns>协议是否是正确的</returns>
|
||||||
|
public abstract bool CheckRight(byte[] content);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 协议内容扩展,发送时根据需要扩展
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">扩展前的基本协议内容</param>
|
||||||
|
/// <returns>扩展后的协议内容</returns>
|
||||||
public byte[] BytesExtend(byte[] content)
|
public byte[] BytesExtend(byte[] content)
|
||||||
{
|
{
|
||||||
|
//自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。
|
||||||
ProtocalLinkerBytesExtend bytesExtend =
|
ProtocalLinkerBytesExtend bytesExtend =
|
||||||
Assembly.Load("ModBus.Net").CreateInstance(this.GetType().FullName + "BytesExtend") as
|
Assembly.Load("ModBus.Net").CreateInstance(this.GetType().FullName + "BytesExtend") as
|
||||||
ProtocalLinkerBytesExtend;
|
ProtocalLinkerBytesExtend;
|
||||||
return bytesExtend.BytesExtend(content);
|
return bytesExtend.BytesExtend(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 协议内容缩减,接收时根据需要缩减
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">缩减前的完整协议内容</param>
|
||||||
|
/// <returns>缩减后的协议内容</returns>
|
||||||
public byte[] BytesDecact(byte[] content)
|
public byte[] BytesDecact(byte[] content)
|
||||||
{
|
{
|
||||||
|
//自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。
|
||||||
ProtocalLinkerBytesExtend bytesExtend =
|
ProtocalLinkerBytesExtend bytesExtend =
|
||||||
Assembly.Load("ModBus.Net").CreateInstance(this.GetType().FullName + "BytesExtend") as
|
Assembly.Load("ModBus.Net").CreateInstance(this.GetType().FullName + "BytesExtend") as
|
||||||
ProtocalLinkerBytesExtend;
|
ProtocalLinkerBytesExtend;
|
||||||
|
|||||||
54
NA200H/ModBus.Net/ProtocalLinkerBytesExtend.cs
Normal file
54
NA200H/ModBus.Net/ProtocalLinkerBytesExtend.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ModBus.Net
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 协议字节伸缩
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ProtocalLinkerBytesExtend
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 协议扩展,协议内容发送前调用
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">扩展前的原始协议内容</param>
|
||||||
|
/// <returns>扩展后的协议内容</returns>
|
||||||
|
public abstract byte[] BytesExtend(byte[] content);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 协议收缩,协议内容接收后调用
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">收缩前的完整协议内容</param>
|
||||||
|
/// <returns>收缩后的协议内容</returns>
|
||||||
|
public abstract byte[] BytesDecact(byte[] content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tcp协议字节伸缩
|
||||||
|
/// </summary>
|
||||||
|
public class ModbusTcpProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
|
||||||
|
{
|
||||||
|
public override byte[] BytesExtend(byte[] content)
|
||||||
|
{
|
||||||
|
//Modbus/Tcp协议扩张,前面加6个字节,前面4个为0,后面两个为协议整体内容的长度
|
||||||
|
byte[] newFormat = new byte[6 + content.Length];
|
||||||
|
int tag = 0;
|
||||||
|
ushort leng = (ushort)content.Length;
|
||||||
|
Array.Copy(ValueHelper.Instance.GetBytes(tag), 0, newFormat, 0, 4);
|
||||||
|
Array.Copy(ValueHelper.Instance.GetBytes(leng), 0, newFormat, 4, 2);
|
||||||
|
Array.Copy(content, 0, newFormat, 6, content.Length);
|
||||||
|
return newFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] BytesDecact(byte[] content)
|
||||||
|
{
|
||||||
|
//Modbus/Tcp协议收缩,抛弃前面6个字节的内容
|
||||||
|
byte[] newContent = new byte[content.Length - 6];
|
||||||
|
Array.Copy(content, 6, newContent, 0, newContent.Length);
|
||||||
|
return newContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,21 +7,40 @@ namespace ModBus.Net
|
|||||||
{
|
{
|
||||||
public abstract class ProtocalUnit : IProtocalFormatting
|
public abstract class ProtocalUnit : IProtocalFormatting
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 格式化,将输入结构转换为字节数组
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public abstract byte[] Format(InputStruct message);
|
public abstract byte[] Format(InputStruct message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 格式化,将对象数组转换为字节数组
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public virtual byte[] Format(params object[] message)
|
public virtual byte[] Format(params object[] message)
|
||||||
{
|
{
|
||||||
return TranslateContent(message);
|
return TranslateContent(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract OutputStruct Unformat(byte[] messageBytes, ref int pos);
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 结构化,将字节数组转换为输出结构。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messageBytes"></param>
|
||||||
|
/// <param name="pos"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public abstract OutputStruct Unformat(byte[] messageBytes, ref int pos);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换静态方法,把对象数组转换为字节数组。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="contents"></param>
|
/// <param name="contents"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static byte[] TranslateContent(params object[] contents)
|
public static byte[] TranslateContent(params object[] contents)
|
||||||
{
|
{
|
||||||
bool b = false;
|
bool b = false;
|
||||||
|
//先查找传入的结构中有没有数组,有的话将其打开
|
||||||
var newContentsList = new List<object>();
|
var newContentsList = new List<object>();
|
||||||
foreach (object content in contents)
|
foreach (object content in contents)
|
||||||
{
|
{
|
||||||
@@ -38,7 +57,9 @@ namespace ModBus.Net
|
|||||||
newContentsList.Add(content);
|
newContentsList.Add(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//重新调用一边这个函数,这个传入的参数中一定没有数组。
|
||||||
if (b) return TranslateContent(newContentsList.ToArray());
|
if (b) return TranslateContent(newContentsList.ToArray());
|
||||||
|
//把参数一个一个翻译为相对应的字节,然后拼成一个队列
|
||||||
var translateTarget = new List<byte>();
|
var translateTarget = new List<byte>();
|
||||||
foreach (object content in contents)
|
foreach (object content in contents)
|
||||||
{
|
{
|
||||||
@@ -96,14 +117,21 @@ namespace ModBus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//最后把队列转换为数组
|
||||||
return translateTarget.ToArray();
|
return translateTarget.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 输入结构
|
||||||
|
/// </summary>
|
||||||
public class InputStruct
|
public class InputStruct
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 输出结构
|
||||||
|
/// </summary>
|
||||||
public class OutputStruct
|
public class OutputStruct
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,61 +4,37 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace ModBus.Net
|
namespace ModBus.Net
|
||||||
{
|
{
|
||||||
public class TcpProtocalLinker : ProtocalLinker
|
public abstract class TcpProtocalLinker : ProtocalLinker
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 连接对象
|
||||||
|
/// </summary>
|
||||||
private TcpSocket _socket;
|
private TcpSocket _socket;
|
||||||
|
|
||||||
|
protected TcpProtocalLinker()
|
||||||
public TcpProtocalLinker()
|
|
||||||
{
|
{
|
||||||
|
//初始化连对象
|
||||||
_socket = new TcpSocket(ConfigurationManager.IP, int.Parse(ConfigurationManager.Port), false);
|
_socket = new TcpSocket(ConfigurationManager.IP, int.Parse(ConfigurationManager.Port), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] SendReceive(byte[] content)
|
public override byte[] SendReceive(byte[] content)
|
||||||
{
|
{
|
||||||
|
//接收数据
|
||||||
byte[] receiveBytes = BytesDecact(_socket.SendMsg(BytesExtend(content)));
|
byte[] receiveBytes = BytesDecact(_socket.SendMsg(BytesExtend(content)));
|
||||||
if (receiveBytes[1] > 127)
|
//容错处理
|
||||||
{
|
if (!CheckRight(content)) return null;
|
||||||
string message;
|
//返回数据
|
||||||
throw new ModbusProtocalErrorException(receiveBytes[2]);
|
|
||||||
}
|
|
||||||
return receiveBytes;
|
return receiveBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override bool SendOnly(byte[] content)
|
public override bool SendOnly(byte[] content)
|
||||||
{
|
{
|
||||||
return _socket.SendMsgWithoutReturn(BytesExtend(content));
|
return _socket.SendMsgWithoutReturn(BytesExtend(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class ProtocalLinkerBytesExtend
|
|
||||||
{
|
|
||||||
public abstract byte[] BytesExtend(byte[] content);
|
|
||||||
|
|
||||||
public abstract byte[] BytesDecact(byte[] content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TcpProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
|
|
||||||
{
|
|
||||||
public override byte[] BytesExtend(byte[] content)
|
|
||||||
{
|
|
||||||
byte[] newFormat = new byte[6 + content.Length];
|
|
||||||
int tag = 0;
|
|
||||||
ushort leng = (ushort)content.Length;
|
|
||||||
Array.Copy(ValueHelper.Instance.GetBytes(tag), 0, newFormat, 0, 4);
|
|
||||||
Array.Copy(ValueHelper.Instance.GetBytes(leng), 0, newFormat, 4, 2);
|
|
||||||
Array.Copy(content, 0, newFormat, 6, content.Length);
|
|
||||||
return newFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override byte[] BytesDecact(byte[] content)
|
|
||||||
{
|
|
||||||
byte[] newContent = new byte[content.Length - 6];
|
|
||||||
Array.Copy(content, 6, newContent, 0, newContent.Length);
|
|
||||||
return newContent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ProtocalErrorException : Exception
|
public class ProtocalErrorException : Exception
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace ModBus.Net
|
|||||||
private readonly string host;
|
private readonly string host;
|
||||||
|
|
||||||
// 2MB 的接收缓冲区,目的是一次接收完服务器发回的消息
|
// 2MB 的接收缓冲区,目的是一次接收完服务器发回的消息
|
||||||
private readonly byte[] m_receiveBuffer = new byte[200000];
|
private readonly byte[] m_receiveBuffer = new byte[1024];
|
||||||
private readonly int port;
|
private readonly int port;
|
||||||
public int m_errorCount = 0;
|
public int m_errorCount = 0;
|
||||||
public int m_receiveCount = 0;
|
public int m_receiveCount = 0;
|
||||||
|
|||||||
@@ -2,20 +2,29 @@
|
|||||||
|
|
||||||
namespace ModBus.Net
|
namespace ModBus.Net
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 值与字节数组之间转换的辅助类,这是一个Singleton类
|
||||||
|
/// 作者:罗圣(Chris L.)
|
||||||
|
/// </summary>
|
||||||
public class ValueHelper
|
public class ValueHelper
|
||||||
{
|
{
|
||||||
|
|
||||||
protected static bool _littleEndian = false;
|
protected static bool _littleEndian = false;
|
||||||
|
|
||||||
protected ValueHelper()
|
protected ValueHelper()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 协议中的内容构造是否小端的,默认是大端构造协议。
|
||||||
|
/// </summary>
|
||||||
public static bool LittleEndian
|
public static bool LittleEndian
|
||||||
{
|
{
|
||||||
get { return _littleEndian; }
|
get { return _littleEndian; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_littleEndian = value;
|
_littleEndian = value;
|
||||||
|
//这里需要重点说明,因为.net默认是小端构造法,所以目标协议是大端的话反而需要调用小端构造协议,把小端反转为大端。
|
||||||
_Instance = LittleEndian ? new ValueHelper() : new LittleEndianValueHelper();
|
_Instance = LittleEndian ? new ValueHelper() : new LittleEndianValueHelper();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,15 @@ namespace NA200H.UI.ConsoleApp
|
|||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
//先初始化一个协议转换器,这里构造Modbus/Tcp协议。
|
||||||
BaseProtocal wrapper = new ModbusTcpProtocal();
|
BaseProtocal wrapper = new ModbusTcpProtocal();
|
||||||
|
|
||||||
|
//调用方法一:手动构造
|
||||||
|
//第一步:先生成一个输入信息的object数组
|
||||||
object[] inputObjects = new object[]{(byte)0x11,(byte)0x01,(short)0x13,(short)0x25};
|
object[] inputObjects = new object[]{(byte)0x11,(byte)0x01,(short)0x13,(short)0x25};
|
||||||
|
//第二步:向仪器发送这个信息,并接收信息
|
||||||
byte[] outputBytes = wrapper.SendReceive(inputObjects);
|
byte[] outputBytes = wrapper.SendReceive(inputObjects);
|
||||||
|
//第三步:输出信息
|
||||||
for (int i = 0; i < outputBytes.Length; i++)
|
for (int i = 0; i < outputBytes.Length; i++)
|
||||||
{
|
{
|
||||||
Console.WriteLine(outputBytes[i]);
|
Console.WriteLine(outputBytes[i]);
|
||||||
@@ -24,8 +29,12 @@ namespace NA200H.UI.ConsoleApp
|
|||||||
Console.Read();
|
Console.Read();
|
||||||
Console.Read();
|
Console.Read();
|
||||||
|
|
||||||
|
//调用方法二:自动构造
|
||||||
|
//第一步:先生成一个输入结构体,然后向这个结构体中填写数据
|
||||||
ReadCoilStatusModbusProtocal.ReadCoilStatusInputStruct readCoilStatusInputStruct = new ReadCoilStatusModbusProtocal.ReadCoilStatusInputStruct(0x11, "Q20", 0x25);
|
ReadCoilStatusModbusProtocal.ReadCoilStatusInputStruct readCoilStatusInputStruct = new ReadCoilStatusModbusProtocal.ReadCoilStatusInputStruct(0x11, "Q20", 0x25);
|
||||||
|
//第二步:再生成一个输出结构体,执行相应协议的发送指令,并将输出信息自动转换到输出结构体中
|
||||||
ReadCoilStatusModbusProtocal.ReadCoilStatusOutputStruct readCoilStatusOutputStruct = (ReadCoilStatusModbusProtocal.ReadCoilStatusOutputStruct)wrapper.SendReceive(wrapper["ReadCoilStatusModbusProtocal"], readCoilStatusInputStruct);
|
ReadCoilStatusModbusProtocal.ReadCoilStatusOutputStruct readCoilStatusOutputStruct = (ReadCoilStatusModbusProtocal.ReadCoilStatusOutputStruct)wrapper.SendReceive(wrapper["ReadCoilStatusModbusProtocal"], readCoilStatusInputStruct);
|
||||||
|
//第三步:读取这个输出结构体的信息。
|
||||||
for (int i = 0; i < readCoilStatusOutputStruct.CoilStatus.Length; i++)
|
for (int i = 0; i < readCoilStatusOutputStruct.CoilStatus.Length; i++)
|
||||||
{
|
{
|
||||||
Console.WriteLine(readCoilStatusOutputStruct.CoilStatus[i]);
|
Console.WriteLine(readCoilStatusOutputStruct.CoilStatus[i]);
|
||||||
|
|||||||
Reference in New Issue
Block a user