2014-08-28 update 1 change sln name

This commit is contained in:
parallelbgls@outlook.com
2014-08-28 11:12:37 +08:00
parent e0fea8731e
commit 32c497342b
39 changed files with 0 additions and 0 deletions

View File

@@ -1,63 +0,0 @@
using System.Collections.Generic;
namespace ModBus.Net
{
/// <summary>
/// 数据单元翻译器
/// </summary>
public abstract class AddressTranslator
{
protected static AddressTranslator _instance;
public Dictionary<string, short> TransDictionary;
public abstract ushort AddressTranslate(string address);
}
/// <summary>
/// NA200H数据单元翻译器
/// </summary>
public class AddressTranslatorNA200H : AddressTranslator
{
private AddressTranslatorNA200H()
{
TransDictionary = new Dictionary<string, short>();
TransDictionary.Add("Q", 0);
TransDictionary.Add("M", 10000);
TransDictionary.Add("N", 20000);
TransDictionary.Add("I", 0);
TransDictionary.Add("S", 10000);
TransDictionary.Add("IW", 0);
TransDictionary.Add("SW", 5000);
TransDictionary.Add("E", 10000);
TransDictionary.Add("MW", 0);
TransDictionary.Add("NW", 10000);
TransDictionary.Add("QW", 20000);
TransDictionary.Add("CLOCK", 30000);
TransDictionary.Add("V", 0);
}
public static AddressTranslator GetInstance()
{
if (_instance == null)
{
_instance = new AddressTranslatorNA200H();
}
return _instance;
}
public override ushort AddressTranslate(string address)
{
address = address.ToUpper();
int i = 0;
int t;
while (!int.TryParse(address[i].ToString(), out t) && i < address.Length)
{
i++;
}
if (i == 0) return ushort.Parse(address);
string head = address.Substring(0, i);
string tail = address.Substring(i);
return (ushort) (TransDictionary[head] + ushort.Parse(tail) - 1);
}
}
}

View File

@@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net
{
public abstract class BaseConnector
{
public abstract bool Connect();
public abstract bool Disconnect();
public abstract bool SendMsgWithoutReturn(byte[] message);
public abstract byte[] SendMsg(byte[] message);
}
}

View File

@@ -1,99 +0,0 @@
using System;
using System.Collections.Generic;
using System.Reflection;
namespace ModBus.Net
{
/// <summary>
/// 基本协议
/// </summary>
public abstract class BaseProtocal
{
/// <summary>
/// 发送数据
/// </summary>
/// <param name="content">需要发送的数据</param>
/// <returns>数据是否正确接收</returns>
protected ProtocalLinker _protocalLinker;
protected BaseProtocal()
{
Protocals = new Dictionary<string, ProtocalUnit>();
}
/// <summary>
/// 协议索引器,这是一个懒加载协议,当字典中不存在协议时自动加载协议,否则调用已经加载的协议
/// </summary>
/// <param name="protocalName">协议的类的名称</param>
/// <returns></returns>
public ProtocalUnit this[string protocalName]
{
get
{
if (Protocals.ContainsKey(protocalName))
{
return Protocals[protocalName];
}
//自动寻找存在的协议并将其加载
var protocalUnit =
Assembly.Load("ModBus.Net").CreateInstance("ModBus.Net." + protocalName) as ProtocalUnit;
if (protocalUnit == null) throw new InvalidCastException("没有相应的协议内容");
Register(protocalUnit);
return Protocals[protocalName];
}
}
protected Dictionary<string, ProtocalUnit> Protocals { get; private set; }
protected void Register(ProtocalUnit linkProtocal)
{
if (linkProtocal == null) return;
Protocals.Add(linkProtocal.GetType().Name, linkProtocal);
}
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public virtual byte[] SendReceive(params object[] content)
{
int t;
return _protocalLinker.SendReceive(ProtocalUnit.TranslateContent(content));
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
/// <param name="unit"></param>
/// <param name="content"></param>
/// <returns></returns>
public virtual OutputStruct SendReceive(ProtocalUnit unit, InputStruct content)
{
int t = 0;
return unit.Unformat(_protocalLinker.SendReceive(unit.Format(content)), ref t);
}
/// <summary>
/// 仅发送数据
/// </summary>
/// <param name="unit"></param>
/// <param name="content"></param>
/// <returns></returns>
public virtual bool SendOnly(ProtocalUnit unit, params object[] 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)
{
return _protocalLinker.SendOnly(unit.Format(content));
}
}
}

View File

@@ -1,92 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net
{
public class Crc16
{
/// <summary>
/// CRC验证表
/// </summary>
public byte[] crc_table = new byte[512];
private static Crc16 _crc16 = null;
public static Crc16 GetInstance()
{
if (_crc16 == null)
{
_crc16 = new Crc16();
}
return _crc16;
}
#region CRC码
/// <summary>
/// 生成CRC码
/// </summary>
/// <param name="message">发送或返回的命令CRC码除外</param>
/// <param name="CRC">生成的CRC码</param>
public short GetCRC(byte[] message, ref byte[] Rcvbuf)
{
int IX,IY,CRC;
int Len = message.Length;
CRC=0xFFFF;
//set all 1
if (Len<=0)
CRC = 0;
else
{
Len--;
for (IX=0;IX<=Len;IX++)
{
CRC=CRC^(message[IX]);
for(IY=0;IY<=7;IY++)
{
if ((CRC&1)!=0 )
CRC=(CRC>>1)^0xA001;
else
CRC=CRC>>1;
//
}
}
}
Rcvbuf[1] = (byte)((CRC & 0xff00)>>8);//高位置
Rcvbuf[0] = (byte)(CRC & 0x00ff); //低位置
CRC= Rcvbuf[0]<<8;
CRC+= Rcvbuf[1];
return (short)CRC;
}
#endregion
#region CRC验证
/// <summary>
/// CRC校验
/// </summary>
/// <param name="src">ST开头&&结尾</param>
/// <returns>十六进制数</returns>
public bool CrcEfficacy(byte[] byteframe)
{
byte[] recvbuff = new byte[2];
byte[] byteArr = new byte[byteframe.Length - 2];
Array.Copy(byteframe, 0, byteArr, 0, byteArr.Length);
GetCRC(byteArr, ref recvbuff);
if (recvbuff[0] == byteframe[byteframe.Length - 2] && recvbuff[1] == byteframe[byteframe.Length - 1])
{
return true;
}
else
{
return false;
}
}
#endregion
}
}

View File

@@ -1,312 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ModBus.Net
{
public class ComConnector : BaseConnector, IDisposable
{
private SerialPort serialPort1 = new SerialPort();
public delegate byte[] getDate(byte[] bts);
private getDate mygetDate;
private string com;
public ComConnector(string com)
{
this.com = com;
serialPort1.PortName = com; //端口号
serialPort1.BaudRate = 9600; //比特率
serialPort1.Parity = Parity.None; //奇偶校验
serialPort1.StopBits = StopBits.One; //停止位
serialPort1.DataBits = 8;
serialPort1.ReadTimeout = 1000; //读超时即在1000内未读到数据就引起超时异常
}
#region
public override bool Connect()
{
if (serialPort1 != null)
{
try
{
serialPort1.Open();
return true;
}
catch
{
return false;
}
}
return false;
}
public override bool Disconnect()
{
if (serialPort1 != null)
{
try
{
serialPort1.Close();
return true;
}
catch
{
return false;
}
}
return false;
}
public void SendMsg(string senStr)
{
byte[] myByte = StringToByte_2(senStr);
SendMsg(myByte);
}
public override byte[] SendMsg(byte[] sendbytes)
{
try
{
if (!serialPort1.IsOpen)
{
serialPort1.Open();
}
serialPort1.Write(sendbytes, 0, sendbytes.Length);
return ReadMsg();
}
catch
{
return null;
}
}
public override bool SendMsgWithoutReturn(byte[] sendbytes)
{
try
{
serialPort1.Write(sendbytes, 0, sendbytes.Length);
return true;
}
catch (Exception)
{
return false;
}
}
public string ReadMsgStr()
{
string rd = "";
byte[] data = ReadMsg();
rd = ByteToString(data);
return rd;
}
public byte[] ReadMsg()
{
if (!serialPort1.IsOpen)
{
serialPort1.Open();
}
byte[] data = new byte[200];
Thread.Sleep(100);
int i = serialPort1.Read(data, 0, serialPort1.BytesToRead);
byte[] returndata = new byte[i];
Array.Copy(data, 0, returndata, 0, i);
serialPort1.Close();
return returndata;
}
#endregion
/// <summary>
/// 串口读(非阻塞方式读串口,直到串口缓冲区中没有数据
/// </summary>
/// <param name="readBuf">串口数据缓冲 </param>
/// <param name="bufRoom">串口数据缓冲空间大小 </param>
/// <param name="HowTime">设置串口读放弃时间 </param>
/// <param name="ByteTime">字节间隔最大时间 </param>
/// <returns>串口实际读入数据个数 </returns>
public int ReadComm(out Byte[] readBuf, int bufRoom, int HowTime, int ByteTime)
{
//throw new System.NotImplementedException();
readBuf = new Byte[64];
Array.Clear(readBuf, 0, readBuf.Length);
int nReadLen, nBytelen;
if (serialPort1.IsOpen == false)
return -1;
nBytelen = 0;
serialPort1.ReadTimeout = HowTime;
try
{
readBuf[nBytelen] = (byte) serialPort1.ReadByte();
byte[] bTmp = new byte[1023];
Array.Clear(bTmp, 0, bTmp.Length);
nReadLen = ReadBlock(out bTmp, bufRoom - 1, ByteTime);
if (nReadLen > 0)
{
Array.Copy(bTmp, 0, readBuf, 1, nReadLen);
nBytelen = 1 + nReadLen;
}
else if (nReadLen == 0)
nBytelen = 1;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
return nBytelen;
}
/// <summary>
/// 串口同步读(阻塞方式读串口,直到串口缓冲区中没有数据,靠字符间间隔超时确定没有数据)
/// </summary>
/// <param name="ReadBuf">串口数据缓冲 </param>
/// <param name="ReadRoom">串口数据缓冲空间大小 </param>
/// <param name="ByteTime">字节间隔最大时间 </param>
/// <returns>从串口实际读入的字节个数 </returns>
public int ReadBlock(out byte[] ReadBuf, int ReadRoom, int ByteTime)
{
//throw new System.NotImplementedException();
ReadBuf = new byte[1024];
Array.Clear(ReadBuf, 0, ReadBuf.Length);
sbyte nBytelen;
//long nByteRead;
if (serialPort1.IsOpen == false)
return 0;
nBytelen = 0;
serialPort1.ReadTimeout = ByteTime;
while (nBytelen < (ReadRoom - 1))
{
try
{
ReadBuf[nBytelen] = (byte) serialPort1.ReadByte();
nBytelen++; // add one
}
catch (Exception ex)
{
throw new Exception(ex.Message);
break;
}
}
ReadBuf[nBytelen] = 0x00;
return nBytelen;
}
/// <summary>
/// 字符数组转字符串16进制
/// </summary>
/// <param name="InBytes"> 二进制字节 </param>
/// <returns>类似"01 02 0F" </returns>
public static string ByteToString(byte[] InBytes)
{
string StringOut = "";
foreach (byte InByte in InBytes)
{
StringOut = StringOut + String.Format("{0:X2}", InByte) + " ";
}
return StringOut.Trim();
}
/// <summary>
/// strhex 转字节数组
/// </summary>
/// <param name="InString">类似"01 02 0F" 用空格分开的 </param>
/// <returns> </returns>
public static byte[] StringToByte(string InString)
{
string[] ByteStrings;
ByteStrings = InString.Split(" ".ToCharArray());
byte[] ByteOut;
ByteOut = new byte[ByteStrings.Length];
for (int i = 0; i <= ByteStrings.Length - 1; i++)
{
ByteOut[i] = byte.Parse(ByteStrings[i], System.Globalization.NumberStyles.HexNumber);
}
return ByteOut;
}
/// <summary>
/// strhex 转字节数组
/// </summary>
/// <param name="InString">类似"01 02 0F" 中间无空格 </param>
/// <returns> </returns>
public static byte[] StringToByte_2(string InString)
{
byte[] ByteOut;
InString = InString.Replace(" ", "");
try
{
string[] ByteStrings = new string[InString.Length/2];
int j = 0;
for (int i = 0; i < ByteStrings.Length; i++)
{
ByteStrings[i] = InString.Substring(j, 2);
j += 2;
}
ByteOut = new byte[ByteStrings.Length];
for (int i = 0; i <= ByteStrings.Length - 1; i++)
{
ByteOut[i] = byte.Parse(ByteStrings[i], System.Globalization.NumberStyles.HexNumber);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
return ByteOut;
}
/// <summary>
/// 字符串 转16进制字符串
/// </summary>
/// <param name="InString">unico </param>
/// <returns>类似“01 0f” </returns>
public static string Str_To_0X(string InString)
{
return ByteToString(UnicodeEncoding.Default.GetBytes(InString));
}
public void Dispose()
{
if (serialPort1 != null)
{
serialPort1.Close();
serialPort1.Dispose();
}
}
}
}

View File

@@ -1,99 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.18444
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModBus.Net {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class ConfigurationManager {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal ConfigurationManager() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModBus.Net.ConfigurationManager", typeof(ConfigurationManager).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 使用此强类型资源类,为所有资源查找
/// 重写当前线程的 CurrentUICulture 属性。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// 查找类似 COM3 的本地化字符串。
/// </summary>
internal static string COM {
get {
return ResourceManager.GetString("COM", resourceCulture);
}
}
/// <summary>
/// 查找类似 192.168.3.247 的本地化字符串。
/// </summary>
internal static string IP {
get {
return ResourceManager.GetString("IP", resourceCulture);
}
}
/// <summary>
/// 查找类似 502 的本地化字符串。
/// </summary>
internal static string Port {
get {
return ResourceManager.GetString("Port", resourceCulture);
}
}
/// <summary>
/// 查找类似 1000 的本地化字符串。
/// </summary>
internal static string SocketTimeOut {
get {
return ResourceManager.GetString("SocketTimeOut", resourceCulture);
}
}
}
}

View File

@@ -1,132 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="COM" xml:space="preserve">
<value>COM3</value>
</data>
<data name="IP" xml:space="preserve">
<value>192.168.3.247</value>
</data>
<data name="Port" xml:space="preserve">
<value>502</value>
</data>
<data name="SocketTimeOut" xml:space="preserve">
<value>1000</value>
</data>
</root>

View File

@@ -1,30 +0,0 @@
namespace ModBus.Net
{
/// <summary>
/// 协议转换的接口
/// </summary>
public interface IProtocalFormatting
{
/// <summary>
/// 从输入结构格式化
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
byte[] Format(InputStruct message);
/// <summary>
/// 从对象的参数数组格式化
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
byte[] Format(params object[] message);
/// <summary>
/// 把仪器返回的内容填充到输出结构中
/// </summary>
/// <param name="messageBytes"></param>
/// <param name="pos"></param>
/// <returns></returns>
OutputStruct Unformat(byte[] messageBytes, ref int pos);
}
}

View File

@@ -1,86 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{124EBEF2-8960-4447-84CF-1D683B1EF7CC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ModBus.Net</RootNamespace>
<AssemblyName>ModBus.Net</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AddressTranslator.cs" />
<Compile Include="BaseProtocal.cs" />
<Compile Include="ComConnector.cs" />
<Compile Include="ModbusUtility.cs" />
<Compile Include="RtuProtocalLinker.cs" />
<Compile Include="ConfigurationManager.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>ConfigurationManager.resx</DependentUpon>
</Compile>
<Compile Include="BaseConnector.cs" />
<Compile Include="CRC16.cs" />
<Compile Include="IProtocalFormatting.cs" />
<Compile Include="ModbusRtuProtocal.cs" />
<Compile Include="ModbusRtuProtocalLinker.cs" />
<Compile Include="ModbusTcpProtocalLinker.cs" />
<Compile Include="ProtocalLinker.cs" />
<Compile Include="ProtocalLinkerBytesExtend.cs" />
<Compile Include="ProtocalUnit.cs" />
<Compile Include="ModbusProtocal.cs" />
<Compile Include="ModbusTcpProtocal.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TcpConnector.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="TcpProtocalLinker.cs" />
<Compile Include="ValueHelper.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="ConfigurationManager.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>ConfigurationManager.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -1,817 +0,0 @@
using System;
using System.Collections.Generic;
public enum ModbusProtocalReg
{
ReadCoilStatus = 1,
ReadInputStatus = 2,
ReadHoldRegister = 3,
ReadInputRegister = 4,
WriteOneCoil = 5,
WriteOneRegister = 6,
WriteMultiCoil = 15,
WriteMultiRegister = 16,
GetSystemTime = 3,
SetSystemTime = 16,
ReadVariable = 20,
WriteVariable = 21,
};
namespace ModBus.Net
{
public abstract class ModbusProtocal : BaseProtocal
{
}
/// <summary>
/// 读线圈状态
/// </summary>
public class ReadCoilStatusModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadCoilStatusInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte coilCount = ValueHelper.Instance.GetByte(messageBytes, ref flag);
var coilStatusArr = new bool[coilCount * 8];
for (int i = 0; i < coilCount; i++)
{
byte coilStatusGet = ValueHelper.Instance.GetByte(messageBytes, ref flag);
for (int j = 0; j < 8; j++)
{
if (coilStatusGet % 2 == 0) coilStatusArr[8 * i + j] = false;
else coilStatusArr[8 * i + j] = true;
coilStatusGet /= 2;
}
}
return new ReadCoilStatusOutputStruct(belongAddress, functionCode, coilCount * 8, coilStatusArr);
}
public class ReadCoilStatusInputStruct : InputStruct
{
public ReadCoilStatusInputStruct(byte belongAddress, string startAddress, ushort getCount)
{
BelongAddress = belongAddress;
FunctionCode = (int)ModbusProtocalReg.ReadCoilStatus;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
GetCount = getCount;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort GetCount { get; private set; }
}
public class ReadCoilStatusOutputStruct : OutputStruct
{
public ReadCoilStatusOutputStruct(byte belongAddress, byte functionCode,
int coilCount, bool[] coilStatus)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
CoilCount = coilCount;
CoilStatus = coilStatus.Clone() as bool[];
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public int CoilCount { get; private set; }
public bool[] CoilStatus { get; private set; }
}
}
/// <summary>
/// 读输入状态协
/// </summary>
public class ReadInputStatusModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadInputStatusInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte inputCount = ValueHelper.Instance.GetByte(messageBytes, ref flag);
var inputStatusArr = new bool[inputCount * 8];
for (int i = 0; i < inputCount; i++)
{
byte inputStatusGet = ValueHelper.Instance.GetByte(messageBytes, ref flag);
for (int j = 0; j < 8; j++)
{
if (inputStatusGet % 2 == 0) inputStatusArr[8 * i + j] = false;
else inputStatusArr[8 * i + j] = true;
inputStatusGet /= 2;
}
}
return new ReadInputStatusOutputStruct(belongAddress, functionCode, inputCount * 8,
inputStatusArr);
}
public class ReadInputStatusInputStruct : InputStruct
{
public ReadInputStatusInputStruct(byte belongAddress, string startAddress, ushort getCount)
{
BelongAddress = belongAddress;
FunctionCode = (int)ModbusProtocalReg.ReadInputStatus;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
GetCount = getCount;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort GetCount { get; private set; }
}
public class ReadInputStatusOutputStruct : OutputStruct
{
public ReadInputStatusOutputStruct(byte belongAddress, byte functionCode,
int inputCount, bool[] inputStatus)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
InputCount = inputCount;
InputStatus = inputStatus.Clone() as bool[];
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public int InputCount { get; private set; }
public bool[] InputStatus { get; private set; }
}
}
/// <summary>
/// 读保持型寄存器
/// </summary>
public class ReadHoldRegisterModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadHoldRegisterInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte holdRegisterCount = ValueHelper.Instance.GetByte(messageBytes, ref flag);
var holdRegisterArr = new ushort[holdRegisterCount / 2];
for (int i = 0; i < holdRegisterCount / 2; i++)
{
holdRegisterArr[i] = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
}
return new ReadHoldRegisterOutputStruct(belongAddress, functionCode, holdRegisterCount / 2,
holdRegisterArr);
}
public class ReadHoldRegisterInputStruct : InputStruct
{
public ReadHoldRegisterInputStruct(byte belongAddress, string startAddress, ushort getCount)
{
BelongAddress = belongAddress;
FunctionCode = (int)ModbusProtocalReg.ReadHoldRegister;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
GetCount = getCount;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort GetCount { get; private set; }
}
public class ReadHoldRegisterOutputStruct : OutputStruct
{
public ReadHoldRegisterOutputStruct(byte belongAddress, byte functionCode,
int holdRegisterCount, ushort[] holdRegisterStatus)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
HoldRegisterCount = holdRegisterCount;
HoldRegisterStatus = holdRegisterStatus.Clone() as ushort[];
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public int HoldRegisterCount { get; private set; }
public ushort[] HoldRegisterStatus { get; private set; }
}
}
/// <summary>
/// 读输入型寄存器
/// </summary>
public class ReadInputRegisterModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadInputRegisterInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
if (messageBytes.Length == 19 && messageBytes[15] == 0 && messageBytes[17] == 0 && messageBytes[18] == 0)
{
byte belongAddress = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte eventByteCount = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte soeProperty = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte soeEvent = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte month = ValueHelper.Instance.GetByte(messageBytes, ref flag);
int year = ValueHelper.Instance.GetByte(messageBytes, ref flag) + 2002;
byte hour = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte day = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte second = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte minute = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort millisecond = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort testPoint = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
flag += 1;
byte testValue = ValueHelper.Instance.GetByte(messageBytes, ref flag);
flag += 1;
flag += 1;
return new ReadEventOutputStruct(belongAddress, functionCode, eventByteCount, soeProperty,
soeEvent,
new DateTime(year, month == 0 ? 1 : 0, day == 0 ? 1 : 0, hour, minute, second, millisecond),
testPoint, testValue);
}
else
{
byte belongAddress = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte inputRegisterCount = ValueHelper.Instance.GetByte(messageBytes, ref flag);
var holdRegisterArr = new ushort[inputRegisterCount / 2];
for (int i = 0; i < inputRegisterCount / 2; i++)
{
holdRegisterArr[i] = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
}
return new ReadInputRegisterOutputStruct(belongAddress, functionCode, inputRegisterCount / 2,
holdRegisterArr);
}
}
public class ReadEventOutputStruct : OutputStruct
{
public ReadEventOutputStruct(byte belongAddress, byte functionCode,
byte eventByteCount, byte soeProperty, byte soeEvent, DateTime time, ushort testPoint,
byte testValue)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
EventByteCount = eventByteCount;
SoeProperty = soeProperty;
SoeEvent = soeEvent;
TestTime = time;
TestPoint = testPoint;
TestValue = testValue;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public byte EventByteCount { get; private set; }
public byte SoeProperty { get; private set; }
public byte SoeEvent { get; private set; }
public DateTime TestTime { get; private set; }
public ushort TestPoint { get; private set; }
public byte TestValue { get; private set; }
}
public class ReadInputRegisterInputStruct : InputStruct
{
public ReadInputRegisterInputStruct(byte belongAddress, string startAddress, ushort getCount)
{
BelongAddress = belongAddress;
FunctionCode = (int)ModbusProtocalReg.ReadInputRegister;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
GetCount = getCount;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort GetCount { get; private set; }
}
public class ReadInputRegisterOutputStruct : OutputStruct
{
public ReadInputRegisterOutputStruct(byte belongAddress, byte functionCode,
int inputRegisterCount, ushort[] inputRegisterStatus)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
InputRegisterCount = inputRegisterCount;
InputRegisterStatus = inputRegisterStatus.Clone() as ushort[];
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public int InputRegisterCount { get; private set; }
public ushort[] InputRegisterStatus { get; private set; }
}
}
/// <summary>
/// 读单个线圈状态
/// </summary>
public class WriteOneCoilModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteOneCoilInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.WriteValue ? new byte[] { 0xFF, 0x00 } : new byte[] { 0x00, 0x00 });
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort startAddress = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort writeValue = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new WriteOneCoilOutputStruct(belongAddress, functionCode, startAddress,
writeValue != 0);
}
public class WriteOneCoilInputStruct : InputStruct
{
public WriteOneCoilInputStruct(byte belongAddress, string startAddress, bool writeValue)
{
BelongAddress = belongAddress;
FunctionCode = (int)ModbusProtocalReg.WriteOneCoil;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
WriteValue = writeValue;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public bool WriteValue { get; private set; }
}
public class WriteOneCoilOutputStruct : OutputStruct
{
public WriteOneCoilOutputStruct(byte belongAddress, byte functionCode,
ushort startAddress, bool writeValue)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteValue = writeValue;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public bool WriteValue { get; private set; }
}
}
/// <summary>
/// 写单个寄存器状态
/// </summary>
public class WriteOneRegisterModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteOneRegisterInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.WriteValue);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort startAddress = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort writeValue = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new WriteOneRegisterOutputStruct(belongAddress, functionCode, startAddress, writeValue);
}
public class WriteOneRegisterInputStruct : InputStruct
{
public WriteOneRegisterInputStruct(byte belongAddress, string startAddress, ushort writeValue)
{
BelongAddress = belongAddress;
FunctionCode = (int)ModbusProtocalReg.WriteOneRegister;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
WriteValue = writeValue;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteValue { get; private set; }
}
public class WriteOneRegisterOutputStruct : OutputStruct
{
public WriteOneRegisterOutputStruct(byte belongAddress, byte functionCode,
ushort startAddress, ushort writeValue)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteValue = writeValue;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteValue { get; private set; }
}
}
/// <summary>
/// 写多个线圈状态
/// </summary>
public class WriteMultiCoilModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteMultiCoilInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.WriteCount, r_message.WriteByteCount, r_message.WriteValue);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort startAddress = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort writeCount = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new WriteMultiCoilOutputStruct(belongAddress, functionCode, startAddress, writeCount);
}
public class WriteMultiCoilInputStruct : InputStruct
{
public WriteMultiCoilInputStruct(byte belongAddress, string startAddress, bool[] writeValue)
{
BelongAddress = belongAddress;
FunctionCode = (int)ModbusProtocalReg.WriteMultiCoil;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
WriteCount = (ushort)writeValue.Length;
WriteByteCount = WriteCount % 8 > 0 ? (byte)(WriteCount / 8 + 1) : (byte)(WriteCount / 8);
WriteValue = new byte[WriteByteCount];
for (int i = 0; i < writeValue.Length; i += 8)
{
int bytenum = 0;
for (int j = 7; j >= 0; j--)
{
int t = i + j < writeValue.Length && writeValue[i + j] ? 1 : 0;
bytenum = bytenum * 2 + t;
}
WriteValue[i / 8] = (byte)bytenum;
}
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteCount { get; private set; }
public byte WriteByteCount { get; private set; }
public byte[] WriteValue { get; private set; }
}
public class WriteMultiCoilOutputStruct : OutputStruct
{
public WriteMultiCoilOutputStruct(byte belongAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteCount = writeCount;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteCount { get; private set; }
}
}
/// <summary>
/// 写多个寄存器状态
/// </summary>
public class WriteMultiRegisterModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteMultiRegisterInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.WriteCount, r_message.WriteByteCount, r_message.WriteValue);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort startAddress = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort writeCount = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new WriteMultiRegisterOutputStruct(belongAddress, functionCode, startAddress,
writeCount);
}
public class WriteMultiRegisterInputStruct : InputStruct
{
public WriteMultiRegisterInputStruct(byte belongAddress, string startAddress, object[] writeValue)
{
BelongAddress = belongAddress;
FunctionCode = (int)ModbusProtocalReg.WriteMultiRegister;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
WriteCount = (ushort)writeValue.Length;
WriteByteCount = (byte)(WriteCount * 2);
WriteValue = writeValue.Clone() as object[];
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteCount { get; private set; }
public byte WriteByteCount { get; private set; }
public object[] WriteValue { get; private set; }
}
public class WriteMultiRegisterOutputStruct : OutputStruct
{
public WriteMultiRegisterOutputStruct(byte belongAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteCount = writeCount;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteCount { get; private set; }
}
}
/// <summary>
/// 读系统时间
/// </summary>
public class GetSystemTimeModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (GetSystemTimeInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte writeByteCount = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort year = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
byte day = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte month = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort hour = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
byte second = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte minute = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort millisecond = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new GetSystemTimeOutputStruct(belongAddress, functionCode, writeByteCount, year, day,
month, hour, second, minute, millisecond);
}
public class GetSystemTimeInputStruct : InputStruct
{
public GetSystemTimeInputStruct(byte belongAddress)
{
BelongAddress = belongAddress;
FunctionCode = (int)ModbusProtocalReg.GetSystemTime;
StartAddress = 30000;
GetCount = 5;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort GetCount { get; private set; }
}
public class GetSystemTimeOutputStruct : OutputStruct
{
public GetSystemTimeOutputStruct(byte belongAddress, byte functionCode,
byte writeByteCount, ushort year, byte day, byte month, ushort hour, byte second, byte minute,
ushort millisecond)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
WriteByteCount = writeByteCount;
Time = new DateTime(year, month, day, hour, minute, second, millisecond);
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public byte WriteByteCount { get; private set; }
public DateTime Time { get; private set; }
}
}
/// <summary>
/// 写系统时间
/// </summary>
public class SetSystemTimeModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (SetSystemTimeInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.WriteCount, r_message.WriteByteCount, r_message.Year,
r_message.Day,
r_message.Month, r_message.Hour, r_message.Second, r_message.Minute, r_message.Millisecond);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort startAddress = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort writeCount = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new SetSystemTimeOutputStruct(belongAddress, functionCode, startAddress, writeCount);
}
public class SetSystemTimeInputStruct : InputStruct
{
public SetSystemTimeInputStruct(byte belongAddress, DateTime time)
{
BelongAddress = belongAddress;
FunctionCode = (int)ModbusProtocalReg.SetSystemTime;
StartAddress = 30000;
WriteCount = 5;
WriteByteCount = 10;
Year = (ushort)time.Year;
Day = (byte)time.Day;
Month = (byte)time.Month;
Hour = (ushort)time.Hour;
Second = (byte)time.Second;
Minute = (byte)time.Minute;
Millisecond = (ushort)time.Millisecond;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteCount { get; private set; }
public byte WriteByteCount { get; private set; }
public ushort Year { get; private set; }
public byte Day { get; private set; }
public byte Month { get; private set; }
public ushort Hour { get; private set; }
public byte Second { get; private set; }
public byte Minute { get; private set; }
public ushort Millisecond { get; private set; }
}
public class SetSystemTimeOutputStruct : OutputStruct
{
public SetSystemTimeOutputStruct(byte belongAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteCount = writeCount;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteCount { get; private set; }
}
}
public class ProtocalErrorException : Exception
{
public ProtocalErrorException(string message)
: base(message)
{
}
}
public class ModbusProtocalErrorException : ProtocalErrorException
{
public int ErrorMessageNumber { get; private set; }
private static readonly Dictionary<int, string> ProtocalErrorDictionary = new Dictionary<int, string>()
{
{1, "ILLEGAL_FUNCTION"},
{2, "ILLEGAL_DATA_ACCESS"},
{3, "ILLEGAL_DATA_VALUE"},
{4, "SLAVE_DEVICE_FAILURE"},
{5, "ACKNOWLWDGE"},
{6, "SLAVE_DEVICE_BUSY"},
{500, "TCP_ILLEGAL_LENGTH"},
{501, "RTU_ILLEGAL_CRC"},
};
public ModbusProtocalErrorException(int messageNumber)
: base(ProtocalErrorDictionary[messageNumber])
{
ErrorMessageNumber = messageNumber;
}
}
}

View File

@@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net
{
public class ModbusRtuProtocal : ModbusProtocal
{
public ModbusRtuProtocal()
{
_protocalLinker = new ModbusRtuProtocalLinker();
}
public ModbusRtuProtocal(string com)
{
_protocalLinker = new ModbusRtuProtocalLinker(com);
}
}
}

View File

@@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net
{
class ModbusRtuProtocalLinker : RtuProtocalLinker
{
public override bool CheckRight(byte[] content)
{
if (!Crc16.GetInstance().CrcEfficacy(content))
{
throw new ModbusProtocalErrorException(501);
}
if (content[1] > 127)
{
throw new ModbusProtocalErrorException(content[2]);
}
return true;
}
public ModbusRtuProtocalLinker() : base()
{
}
public ModbusRtuProtocalLinker(string com) : base(com)
{
}
}
}

View File

@@ -1,21 +0,0 @@
using System;
namespace ModBus.Net
{
/// <summary>
/// Modbus/Tcp协议
/// </summary>
public class ModbusTcpProtocal : ModbusProtocal
{
//将连接器设置为Tcp连接器
public ModbusTcpProtocal()
{
_protocalLinker = new ModbusTcpProtocalLinker();
}
public ModbusTcpProtocal(string ip)
{
_protocalLinker = new ModbusTcpProtocalLinker(ip);
}
}
}

View File

@@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net
{
public class ModbusTcpProtocalLinker : TcpProtocalLinker
{
public override bool CheckRight(byte[] content)
{
if (content[5] != content.Length - 6)
{
throw new ModbusProtocalErrorException(500);
}
if (content[7] > 127)
{
throw new ModbusProtocalErrorException(content[2]);
}
return true;
}
public ModbusTcpProtocalLinker() : base()
{
}
public ModbusTcpProtocalLinker(string ip) : base(ip)
{
}
}
}

View File

@@ -1,89 +0,0 @@
using System;
using System.Collections;
using System.Windows.Forms;
public enum ModbusType
{
Rtu = 0,
Tcp = 1,
}
namespace ModBus.Net
{
public class ModbusUtility
{
private BaseProtocal _wrapper;
private ModbusType _modbusType;
public ModbusType ModbusType
{
get
{
return _modbusType;
}
set
{
_modbusType = value;
switch (_modbusType)
{
case ModbusType.Rtu:
{
_wrapper = new ModbusRtuProtocal();
break;
}
case ModbusType.Tcp:
{
_wrapper = new ModbusTcpProtocal();
break;
}
}
}
}
private static ModbusUtility _modbusUtility;
private ModbusUtility()
{
ModbusType = ModbusType.Rtu;
}
public static ModbusUtility GetInstance()
{
return _modbusUtility ?? (_modbusUtility = new ModbusUtility());
}
public ushort[] ReadHoldRegister(byte belongAddress, string startAddress, ushort getCount)
{
try
{
var inputStruct = new ReadHoldRegisterModbusProtocal.ReadHoldRegisterInputStruct(belongAddress, startAddress, getCount);
var outputStruct =
_wrapper.SendReceive(_wrapper["ReadHoldRegisterModbusProtocal"], inputStruct) as
ReadHoldRegisterModbusProtocal.ReadHoldRegisterOutputStruct;
return outputStruct.HoldRegisterStatus;
}
catch
{
return null;
}
}
public bool WriteMultiRegister(byte belongAddress, string startAddress, object[] writeValue)
{
try
{
var inputStruct = new WriteMultiRegisterModbusProtocal.WriteMultiRegisterInputStruct(belongAddress,
startAddress, writeValue);
var outputStruct =
_wrapper.SendReceive(_wrapper["WriteMultiRegisterModbusProtocal"], inputStruct) as
WriteMultiRegisterModbusProtocal.WriteMultiRegisterOutputStruct;
if (outputStruct.WriteCount != writeValue.Length) return false;
return true;
}
catch
{
return false;
}
}
}
}

View File

@@ -1,39 +0,0 @@
using System.Reflection;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("ModBus.Net")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ModBus.Net")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("5e21fad9-c4ec-442e-bc0c-050e7a52b418")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,72 +0,0 @@
using System.Reflection;
namespace ModBus.Net
{
/// <summary>
/// 基本的协议连接器
/// </summary>
public abstract class ProtocalLinker
{
protected BaseConnector _baseConnector;
/// <summary>
/// 发送并接收数据
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
public virtual byte[] SendReceive(byte[] content)
{
//接收数据
byte[] receiveBytes = _baseConnector.SendMsg(BytesExtend(content));
//容错处理
if (!CheckRight(receiveBytes)) return null;
//返回数据
return BytesDecact(receiveBytes);
}
/// <summary>
/// 仅发送数据
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>协议是否正确发送</returns>
public virtual bool SendOnly(byte[] content)
{
return _baseConnector.SendMsgWithoutReturn(BytesExtend(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)
{
//自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。
ProtocalLinkerBytesExtend bytesExtend =
Assembly.Load("ModBus.Net").CreateInstance(this.GetType().FullName + "BytesExtend") as
ProtocalLinkerBytesExtend;
return bytesExtend.BytesExtend(content);
}
/// <summary>
/// 协议内容缩减,接收时根据需要缩减
/// </summary>
/// <param name="content">缩减前的完整协议内容</param>
/// <returns>缩减后的协议内容</returns>
public byte[] BytesDecact(byte[] content)
{
//自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。
ProtocalLinkerBytesExtend bytesExtend =
Assembly.Load("ModBus.Net").CreateInstance(this.GetType().FullName + "BytesExtend") as
ProtocalLinkerBytesExtend;
return bytesExtend.BytesDecact(content);
}
}
}

View File

@@ -1,76 +0,0 @@
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;
}
}
public class ModbusRtuProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
{
public override byte[] BytesExtend(byte[] content)
{
byte[] crc = new byte[2];
//Modbus/Tcp协议扩张增加CRC校验
byte[] newFormat = new byte[content.Length + 2];
Crc16.GetInstance().GetCRC(content, ref crc);
Array.Copy(content, 0, newFormat, 0, content.Length);
Array.Copy(crc, 0, newFormat, newFormat.Length - 2, crc.Length);
return newFormat;
}
public override byte[] BytesDecact(byte[] content)
{
//Modbus/Com协议收缩抛弃后面1个字节的内容
byte[] newContent = new byte[content.Length - 2];
Array.Copy(content, 0, newContent, 0, newContent.Length);
return newContent;
}
}
}

View File

@@ -1,138 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace ModBus.Net
{
public abstract class ProtocalUnit : IProtocalFormatting
{
/// <summary>
/// 格式化,将输入结构转换为字节数组
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public abstract byte[] Format(InputStruct message);
/// <summary>
/// 格式化,将对象数组转换为字节数组
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public virtual byte[] Format(params object[] message)
{
return TranslateContent(message);
}
/// <summary>
/// 结构化,将字节数组转换为输出结构。
/// </summary>
/// <param name="messageBytes"></param>
/// <param name="pos"></param>
/// <returns></returns>
public abstract OutputStruct Unformat(byte[] messageBytes, ref int pos);
/// <summary>
/// 转换静态方法,把对象数组转换为字节数组。
/// </summary>
/// <param name="contents"></param>
/// <returns></returns>
public static byte[] TranslateContent(params object[] contents)
{
bool b = false;
//先查找传入的结构中有没有数组,有的话将其打开
var newContentsList = new List<object>();
foreach (object content in contents)
{
string t = content.GetType().ToString();
if (t.Substring(t.Length - 2, 2) == "[]")
{
b = true;
IEnumerable<object> contentArray =
ArrayList.Adapter((Array)content).ToArray(typeof(object)).OfType<object>();
newContentsList.AddRange(contentArray);
}
else
{
newContentsList.Add(content);
}
}
//重新调用一边这个函数,这个传入的参数中一定没有数组。
if (b) return TranslateContent(newContentsList.ToArray());
//把参数一个一个翻译为相对应的字节,然后拼成一个队列
var translateTarget = new List<byte>();
foreach (object content in contents)
{
string t = content.GetType().ToString();
switch (t)
{
case "System.Int16":
{
translateTarget.AddRange(ValueHelper.Instance.GetBytes((short)content));
break;
}
case "System.Int32":
{
translateTarget.AddRange(ValueHelper.Instance.GetBytes((int)content));
break;
}
case "System.Int64":
{
translateTarget.AddRange(ValueHelper.Instance.GetBytes((long)content));
break;
}
case "System.UInt16":
{
translateTarget.AddRange(ValueHelper.Instance.GetBytes((ushort)content));
break;
}
case "System.UInt32":
{
translateTarget.AddRange(ValueHelper.Instance.GetBytes((uint)content));
break;
}
case "System.UInt64":
{
translateTarget.AddRange(ValueHelper.Instance.GetBytes((ulong)content));
break;
}
case "System.Single":
{
translateTarget.AddRange(ValueHelper.Instance.GetBytes((float)content));
break;
}
case "System.Double":
{
translateTarget.AddRange(ValueHelper.Instance.GetBytes((double)content));
break;
}
case "System.Byte":
{
translateTarget.AddRange(ValueHelper.Instance.GetBytes((byte)content));
break;
}
default:
{
throw new NotImplementedException("没有实现除整数以外的其它转换方式");
}
}
}
//最后把队列转换为数组
return translateTarget.ToArray();
}
}
/// <summary>
/// 输入结构
/// </summary>
public class InputStruct
{
}
/// <summary>
/// 输出结构
/// </summary>
public class OutputStruct
{
}
}

View File

@@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net
{
public abstract class RtuProtocalLinker : ProtocalLinker
{
protected RtuProtocalLinker()
{
//初始化连对象
_baseConnector = new ComConnector(ConfigurationManager.COM);
}
protected RtuProtocalLinker(string com)
{
_baseConnector = new ComConnector(com);
}
}
}

View File

@@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ModBus.Net
{
public abstract class TcpProtocalLinker : ProtocalLinker
{
/// <summary>
/// 连接对象
/// </summary>
protected TcpProtocalLinker()
{
//初始化连对象
_baseConnector = new TcpConnector(ConfigurationManager.IP, int.Parse(ConfigurationManager.Port), false);
}
protected TcpProtocalLinker(string ip)
{
_baseConnector = new TcpConnector(ip, int.Parse(ConfigurationManager.Port), false);
}
}
}

View File

@@ -1,299 +0,0 @@
using System;
using System.Net.Sockets;
using System.Threading;
namespace ModBus.Net
{
/// <summary>
/// Socket收到的数据
/// </summary>
public class SocketMessageEventArgs : EventArgs
{
public SocketMessageEventArgs(byte[] message)
{
Message = message;
}
public byte[] Message { get; set; }
}
/// <summary>
/// Socket收发类
/// 作者本类来源于CSDN并由罗圣Chris L.)根据实际需要修改
/// </summary>
public class TcpConnector : BaseConnector, IDisposable
{
public delegate void ErrorShutdownEventHandler(object sender, EventArgs e);
public delegate void ReceiveMessageHandler(object sender, SocketMessageEventArgs e);
private readonly bool b_AsyncReceive = true;
private readonly string host;
// 2MB 的接收缓冲区,目的是一次接收完服务器发回的消息
private readonly byte[] m_receiveBuffer = new byte[1024];
private readonly int port;
public int m_errorCount = 0;
public int m_receiveCount = 0;
public int m_sendCount = 0;
private TcpClient m_socketClient;
public TcpConnector(string ipaddress, int port, bool isAsync)
{
host = ipaddress;
this.port = port;
b_AsyncReceive = isAsync;
}
public bool SocketIsConnect
{
get { return m_socketClient != null ? m_socketClient.Connected : false; }
}
public void Dispose()
{
if (m_socketClient != null)
{
CloseClientSocket();
m_socketClient.Client.Dispose();
}
}
public event ReceiveMessageHandler MessageReceive;
public event ErrorShutdownEventHandler SocketErrorShutdown;
private void ReceiveMessage(byte[] message)
{
if (MessageReceive != null)
{
MessageReceive(this, new SocketMessageEventArgs(message));
}
}
public override bool Connect()
{
if (m_socketClient != null)
{
Disconnect();
}
lock (this)
{
try
{
m_socketClient = new TcpClient(host, port);
m_socketClient.ReceiveTimeout = 10*1000;
if (m_socketClient.Connected)
{
AddInfo("client connected.");
return true;
}
AddInfo("connect failed.");
return false;
}
catch (Exception err)
{
AddInfo("client connect exception: " + err.Message);
return false;
}
}
}
public override bool Disconnect()
{
lock (this)
{
if (m_socketClient == null)
{
return true;
}
try
{
m_socketClient.Close();
AddInfo("client disconnected successfully.");
return true;
}
catch (Exception err)
{
AddInfo("client disconnected exception: " + err.Message);
return false;
}
finally
{
m_socketClient = null;
}
}
}
private void AddInfo(string message)
{
Console.WriteLine(message);
}
/// <summary>
/// 发送数据,不需要返回任何值
/// </summary>
/// <param name="message">发送的信息</param>
/// <returns>是否发送成功</returns>
public override bool SendMsgWithoutReturn(byte[] message)
{
byte[] datagram = message;
try
{
m_socketClient.Client.Send(datagram);
RefreshSendCount();
//this.AddInfo("send text len = " + datagramText.Length.ToString());
return true;
}
catch (Exception err)
{
AddInfo("send exception: " + err.Message);
CloseClientSocket();
return false;
}
}
/// <summary>
/// 发送数据,需要返回
/// </summary>
/// <param name="message">发送的数据</param>
/// <returns>是否发送成功</returns>
public override byte[] SendMsg(byte[] message)
{
byte[] datagram = message;
try
{
if (!SocketIsConnect)
{
Connect();
}
m_socketClient.Client.Send(datagram);
RefreshSendCount();
//this.AddInfo("send text len = " + datagramText.Length.ToString());
return Receive();
}
catch (Exception err)
{
AddInfo("send exception: " + err.Message);
CloseClientSocket();
return null;
}
}
public byte[] Receive()
{
try
{
// 异步接收回答
if (b_AsyncReceive)
{
m_socketClient.Client.BeginReceive(m_receiveBuffer, 0, m_receiveBuffer.Length, SocketFlags.None,
EndReceiveDatagram, this);
return null;
}
// 同步接收回答
int len = m_socketClient.Client.Receive(m_receiveBuffer, 0, m_receiveBuffer.Length, SocketFlags.None);
if (len > 0)
{
return CheckReplyDatagram(len);
}
return null;
}
catch (Exception err)
{
AddInfo("receive exception: " + err.Message);
CloseClientSocket();
return null;
}
}
/// <summary>
/// 接收消息,并转换成字符串
/// </summary>
/// <param name="len"></param>
private byte[] CheckReplyDatagram(int len)
{
var replyMessage = new byte[len];
Array.Copy(m_receiveBuffer, replyMessage, len);
//this.AddInfo("reply: " + replyMesage);
ReceiveMessage(replyMessage);
RefreshReceiveCount();
if (len <= 0)
{
RefreshErrorCount();
}
return replyMessage;
}
private void RefreshSendCount()
{
m_sendCount++;
}
private void RefreshReceiveCount()
{
m_receiveCount++;
}
private void RefreshErrorCount()
{
m_errorCount++;
}
private void CloseClientSocket()
{
try
{
m_socketClient.Client.Shutdown(SocketShutdown.Both);
m_socketClient.Client.Close();
if (!SocketIsConnect)
{
if (SocketErrorShutdown != null)
{
Thread.Sleep(1000);
SocketErrorShutdown(this, new EventArgs());
AddInfo("socket error disconnected!");
}
}
}
catch (Exception ex)
{
//this.AddInfo("client close exception: " + ex.Message);
}
}
/// <summary>
/// 异步接收消息返回函数
/// </summary>
/// <param name="iar">异步参数</param>
private void EndReceiveDatagram(IAsyncResult iar)
{
try
{
int readBytesLength = m_socketClient.Client.EndReceive(iar);
if (readBytesLength == 0)
{
CloseClientSocket();
}
else // 正常数据包
{
CheckReplyDatagram(readBytesLength);
}
}
catch (Exception err)
{
AddInfo("receive exception: " + err.Message);
CloseClientSocket();
}
}
}
}

View File

@@ -1,271 +0,0 @@
using System;
namespace ModBus.Net
{
/// <summary>
/// 值与字节数组之间转换的辅助类这是一个Singleton类
/// 作者罗圣Chris L.
/// </summary>
public class ValueHelper
{
protected static bool _littleEndian = false;
protected ValueHelper()
{
}
/// <summary>
/// 协议中的内容构造是否小端的,默认是大端构造协议。
/// </summary>
public static bool LittleEndian
{
get { return _littleEndian; }
set
{
_littleEndian = value;
//这里需要重点说明,因为.net默认是小端构造法所以目标协议是大端的话反而需要调用小端构造协议把小端反转为大端。
_Instance = LittleEndian ? new ValueHelper() : new LittleEndianValueHelper();
}
}
#region Factory
protected static ValueHelper _Instance = null;
internal static ValueHelper Instance
{
get
{
if (_Instance == null)
{
_Instance = LittleEndian ? new ValueHelper() : new LittleEndianValueHelper();
}
return _Instance;
}
}
#endregion
public Byte[] GetBytes(byte value)
{
return new[] {value};
}
public virtual Byte[] GetBytes(short value)
{
return BitConverter.GetBytes(value);
}
public virtual Byte[] GetBytes(int value)
{
return BitConverter.GetBytes(value);
}
public virtual Byte[] GetBytes(long value)
{
return BitConverter.GetBytes(value);
}
public virtual Byte[] GetBytes(ushort value)
{
return BitConverter.GetBytes(value);
}
public virtual Byte[] GetBytes(uint value)
{
return BitConverter.GetBytes(value);
}
public virtual Byte[] GetBytes(ulong value)
{
return BitConverter.GetBytes(value);
}
public virtual Byte[] GetBytes(float value)
{
return BitConverter.GetBytes(value);
}
public virtual Byte[] GetBytes(double value)
{
return BitConverter.GetBytes(value);
}
public byte GetByte(byte[] data, ref int pos)
{
byte t = data[pos];
pos += 1;
return t;
}
public virtual short GetShort(byte[] data, ref int pos)
{
short t = BitConverter.ToInt16(data, pos);
pos += 2;
return t;
}
public virtual int GetInt(byte[] data, ref int pos)
{
int t = BitConverter.ToInt32(data, pos);
pos += 4;
return t;
}
public virtual long GetLong(byte[] data, ref int pos)
{
long t = BitConverter.ToInt64(data, pos);
pos += 8;
return t;
}
public virtual ushort GetUShort(byte[] data, ref int pos)
{
ushort t = BitConverter.ToUInt16(data, pos);
pos += 2;
return t;
}
public virtual uint GetUInt(byte[] data, ref int pos)
{
uint t = BitConverter.ToUInt32(data, pos);
pos += 4;
return t;
}
public virtual ulong GetULong(byte[] data, ref int pos)
{
ulong t = BitConverter.ToUInt64(data, 0);
pos += 8;
return t;
}
public virtual float GetFloat(byte[] data, ref int pos)
{
float t = BitConverter.ToSingle(data, 0);
pos += 4;
return t;
}
public virtual double GetDouble(byte[] data, ref int pos)
{
double t = BitConverter.ToDouble(data, 0);
pos += 8;
return t;
}
}
internal class LittleEndianValueHelper : ValueHelper
{
public override Byte[] GetBytes(short value)
{
return Reverse(BitConverter.GetBytes(value));
}
public override Byte[] GetBytes(int value)
{
return Reverse(BitConverter.GetBytes(value));
}
public override Byte[] GetBytes(long value)
{
return Reverse(BitConverter.GetBytes(value));
}
public override Byte[] GetBytes(ushort value)
{
return Reverse(BitConverter.GetBytes(value));
}
public override Byte[] GetBytes(uint value)
{
return Reverse(BitConverter.GetBytes(value));
}
public override Byte[] GetBytes(ulong value)
{
return Reverse(BitConverter.GetBytes(value));
}
public override Byte[] GetBytes(float value)
{
return Reverse(BitConverter.GetBytes(value));
}
public override Byte[] GetBytes(double value)
{
return Reverse(BitConverter.GetBytes(value));
}
public override short GetShort(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 2);
short t = BitConverter.ToInt16(data, pos);
pos += 2;
return t;
}
public override int GetInt(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 4);
int t = BitConverter.ToInt32(data, pos);
pos += 4;
return t;
}
public override long GetLong(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 8);
long t = BitConverter.ToInt64(data, pos);
pos += 8;
return t;
}
public override ushort GetUShort(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 2);
ushort t = BitConverter.ToUInt16(data, pos);
pos += 2;
return t;
}
public override uint GetUInt(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 4);
uint t = BitConverter.ToUInt32(data, pos);
pos += 4;
return t;
}
public override ulong GetULong(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 8);
ulong t = BitConverter.ToUInt64(data, 0);
pos += 8;
return t;
}
public override float GetFloat(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 4);
float t = BitConverter.ToSingle(data, 0);
pos += 4;
return t;
}
public override double GetDouble(byte[] data, ref int pos)
{
Array.Reverse(data, pos, 8);
double t = BitConverter.ToDouble(data, 0);
pos += 8;
return t;
}
private Byte[] Reverse(Byte[] data)
{
Array.Reverse(data);
return data;
}
}
}