update 2014-07-31 3

This commit is contained in:
parallelbgls
2014-07-31 17:09:53 +08:00
parent d9ee83fb89
commit 7395c43572
9 changed files with 1612 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
using System.Collections.Generic;
namespace ModBus.Net
{
public abstract class AddressTranslator
{
protected static AddressTranslator _instance;
public Dictionary<string, short> TransDictionary;
public abstract ushort AddressTranslate(string address);
}
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

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Reflection;
namespace ModBus.Net
{
public abstract class BaseProtocal
{
/// <summary>
/// 发送数据
/// </summary>
/// <param name="content">需要发送的数据</param>
/// <returns>数据是否正确接收</returns>
protected ProtocalLinker _protocalLinker;
protected BaseProtocal()
{
Protocals = new Dictionary<string, ProtocalUnit>();
}
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; }
public void Register(ProtocalUnit linkProtocal)
{
if (linkProtocal == null) return;
Protocals.Add(linkProtocal.GetType().Name, linkProtocal);
}
public virtual OutputStruct SendReceive(ProtocalUnit unit, params object[] content)
{
int t = 0;
return unit.Unformat(_protocalLinker.SendReceive(unit.Format(content)), ref t);
}
public virtual OutputStruct SendReceive(ProtocalUnit unit, InputStruct content)
{
int t = 0;
return unit.Unformat(_protocalLinker.SendReceive(unit.Format(content)), ref t);
}
/// <summary>
/// 接收数据
/// </summary>
/// <returns>接收到的数据</returns>
public virtual bool SendOnly(ProtocalUnit unit, params object[] content)
{
return _protocalLinker.SendOnly(unit.Format(content));
}
public virtual bool SendOnly(ProtocalUnit unit, InputStruct content)
{
return _protocalLinker.SendOnly(unit.Format(content));
}
}
}

View File

@@ -0,0 +1,11 @@
namespace ModBus.Net
{
public interface IProtocalFormatting
{
byte[] Format(InputStruct message);
byte[] Format(params object[] message);
OutputStruct Unformat(byte[] messageBytes, ref int pos);
}
}

View File

@@ -0,0 +1,22 @@
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
{
}
}

View File

@@ -0,0 +1,885 @@
using System;
namespace ModBus.Net
{
public class ModbusTCPProtocal : ModbusProtocal
{
public ModbusTCPProtocal()
{
_protocalLinker = new TCPProtocalLinker();
}
}
public class ReadCoilStatusTCPProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadCoilStatusInputStruct) message;
return Format(r_message.Tag, r_message.Leng, r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
int tag = ValueHelper.Instance.GetInt(messageBytes, ref flag);
ushort leng = ValueHelper.Instance.GetUShort(messageBytes, ref 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(tag, leng, belongAddress, functionCode, coilCount, coilStatusArr);
}
public class ReadCoilStatusInputStruct : InputStruct
{
public ReadCoilStatusInputStruct(byte belongAddress, string startAddress, ushort getCount)
{
Tag = 0;
BelongAddress = belongAddress;
FunctionCode = (int) ModbusProtocalReg.ReadCoilStatus;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
GetCount = getCount;
Leng = 6;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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(int tag, ushort leng, byte belongAddress, byte functionCode,
byte coilCount, bool[] coilStatus)
{
Tag = tag;
Leng = leng;
BelongAddress = belongAddress;
FunctionCode = functionCode;
CoilCount = coilCount*8;
CoilStatus = coilStatus.Clone() as bool[];
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public int CoilCount { get; private set; }
public bool[] CoilStatus { get; private set; }
}
}
public class ReadInputStatusTCPProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadInputStatusInputStruct) message;
return Format(r_message.Tag, r_message.Leng, r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
int tag = ValueHelper.Instance.GetInt(messageBytes, ref flag);
ushort leng = ValueHelper.Instance.GetUShort(messageBytes, ref 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(tag, leng, belongAddress, functionCode, inputCount, inputStatusArr);
}
public class ReadInputStatusInputStruct : InputStruct
{
public ReadInputStatusInputStruct(byte belongAddress, string startAddress, ushort getCount)
{
Tag = 0;
BelongAddress = belongAddress;
FunctionCode = (int) ModbusProtocalReg.ReadInputStatus;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
GetCount = getCount;
Leng = 6;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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(int tag, ushort leng, byte belongAddress, byte functionCode,
byte inputCount, bool[] inputStatus)
{
Tag = tag;
Leng = leng;
BelongAddress = belongAddress;
FunctionCode = functionCode;
InputCount = inputCount*8;
InputStatus = inputStatus.Clone() as bool[];
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public int InputCount { get; private set; }
public bool[] InputStatus { get; private set; }
}
}
public class ReadHoldRegisterTCPProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadHoldRegisterInputStruct) message;
return Format(r_message.Tag, r_message.Leng, r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
int tag = ValueHelper.Instance.GetInt(messageBytes, ref flag);
ushort leng = ValueHelper.Instance.GetUShort(messageBytes, ref 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(tag, leng, belongAddress, functionCode, holdRegisterCount,
holdRegisterArr);
}
public class ReadHoldRegisterInputStruct : InputStruct
{
public ReadHoldRegisterInputStruct(byte belongAddress, string startAddress, ushort getCount)
{
Tag = 0;
BelongAddress = belongAddress;
FunctionCode = (int) ModbusProtocalReg.ReadHoldRegister;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
GetCount = getCount;
Leng = 6;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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(int tag, ushort leng, byte belongAddress, byte functionCode,
byte holdRegisterCount, ushort[] holdRegisterStatus)
{
Tag = tag;
Leng = leng;
BelongAddress = belongAddress;
FunctionCode = functionCode;
HoldRegisterCount = holdRegisterCount/2;
HoldRegisterStatus = holdRegisterStatus.Clone() as ushort[];
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public int HoldRegisterCount { get; private set; }
public ushort[] HoldRegisterStatus { get; private set; }
}
}
public class ReadInputRegisterTCPProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadInputRegisterInputStruct) message;
return Format(r_message.Tag, r_message.Leng, r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
if (messageBytes.Length == 25)
{
int tag = ValueHelper.Instance.GetInt(messageBytes, ref flag);
ushort leng = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
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(tag, leng, belongAddress, functionCode, eventByteCount, soeProperty,
soeEvent,
new DateTime(year, month == 0 ? 1 : 0, day == 0 ? 1 : 0, hour, minute, second, millisecond),
testPoint, testValue);
}
else
{
int tag = ValueHelper.Instance.GetInt(messageBytes, ref flag);
ushort leng = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
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(tag, leng, belongAddress, functionCode, inputRegisterCount,
holdRegisterArr);
}
}
public class ReadEventOutputStruct : OutputStruct
{
public ReadEventOutputStruct(int tag, ushort leng, byte belongAddress, byte functionCode,
byte eventByteCount, byte soeProperty, byte soeEvent, DateTime time, ushort testPoint, byte testValue)
{
Tag = tag;
Leng = leng;
BelongAddress = belongAddress;
FunctionCode = functionCode;
EventByteCount = eventByteCount;
SoeProperty = soeProperty;
SoeEvent = soeEvent;
TestTime = time;
TestPoint = testPoint;
TestValue = testValue;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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)
{
Tag = 0;
BelongAddress = belongAddress;
FunctionCode = (int) ModbusProtocalReg.ReadInputRegister;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
GetCount = getCount;
Leng = 6;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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(int tag, ushort leng, byte belongAddress, byte functionCode,
byte inputRegisterCount, ushort[] inputRegisterStatus)
{
Tag = tag;
Leng = leng;
BelongAddress = belongAddress;
FunctionCode = functionCode;
InputRegisterCount = inputRegisterCount/2;
InputRegisterStatus = inputRegisterStatus.Clone() as ushort[];
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public int InputRegisterCount { get; private set; }
public ushort[] InputRegisterStatus { get; private set; }
}
}
public class WriteOneCoilTCPProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteOneCoilInputStruct) message;
return Format(r_message.Tag, r_message.Leng, 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)
{
int tag = ValueHelper.Instance.GetInt(messageBytes, ref flag);
ushort leng = ValueHelper.Instance.GetUShort(messageBytes, ref 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(tag, leng, belongAddress, functionCode, startAddress,
writeValue == 0 ? false : true);
}
public class WriteOneCoilInputStruct : InputStruct
{
public WriteOneCoilInputStruct(byte belongAddress, string startAddress, bool writeValue)
{
Tag = 0;
BelongAddress = belongAddress;
FunctionCode = (int) ModbusProtocalReg.WriteOneCoil;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
WriteValue = writeValue;
Leng = 6;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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(int tag, ushort leng, byte belongAddress, byte functionCode,
ushort startAddress, bool writeValue)
{
Tag = tag;
Leng = leng;
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteValue = writeValue;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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 WriteOneRegisterTCPProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteOneRegisterInputStruct) message;
return Format(r_message.Tag, r_message.Leng, r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.WriteValue);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
int tag = ValueHelper.Instance.GetInt(messageBytes, ref flag);
ushort leng = ValueHelper.Instance.GetUShort(messageBytes, ref 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(tag, leng, belongAddress, functionCode, startAddress, writeValue);
}
public class WriteOneRegisterInputStruct : InputStruct
{
public WriteOneRegisterInputStruct(byte belongAddress, string startAddress, ushort writeValue)
{
Tag = 0;
BelongAddress = belongAddress;
FunctionCode = (int) ModbusProtocalReg.WriteOneRegister;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
WriteValue = writeValue;
Leng = 6;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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(int tag, ushort leng, byte belongAddress, byte functionCode,
ushort startAddress, ushort writeValue)
{
Tag = tag;
Leng = leng;
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteValue = writeValue;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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 WriteMultiCoilTCPProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteMultiCoilInputStruct) message;
return Format(r_message.Tag, r_message.Leng, 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)
{
int tag = ValueHelper.Instance.GetInt(messageBytes, ref flag);
ushort leng = ValueHelper.Instance.GetUShort(messageBytes, ref 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(tag, leng, belongAddress, functionCode, startAddress, writeCount);
}
public class WriteMultiCoilInputStruct : InputStruct
{
public WriteMultiCoilInputStruct(byte belongAddress, string startAddress, bool[] writeValue)
{
Tag = 0;
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;
}
Leng = (ushort) (7 + WriteByteCount);
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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(int tag, ushort leng, byte belongAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
Tag = tag;
Leng = leng;
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteCount = writeCount;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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 WriteMultiRegisterTCPProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteMultiRegisterInputStruct) message;
return Format(r_message.Tag, r_message.Leng, 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)
{
int tag = ValueHelper.Instance.GetInt(messageBytes, ref flag);
ushort leng = ValueHelper.Instance.GetUShort(messageBytes, ref 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(tag, leng, belongAddress, functionCode, startAddress, writeCount);
}
public class WriteMultiRegisterInputStruct : InputStruct
{
public WriteMultiRegisterInputStruct(byte belongAddress, string startAddress, ushort[] writeValue)
{
Tag = 0;
BelongAddress = belongAddress;
FunctionCode = (int) ModbusProtocalReg.WriteMultiRegister;
StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress);
WriteCount = (ushort) writeValue.Length;
WriteByteCount = (byte) (WriteCount*2);
WriteValue = writeValue.Clone() as ushort[];
Leng = (ushort) (7 + WriteByteCount);
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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[] WriteValue { get; private set; }
}
public class WriteMultiRegisterOutputStruct : OutputStruct
{
public WriteMultiRegisterOutputStruct(int tag, ushort leng, byte belongAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
Tag = tag;
Leng = leng;
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteCount = writeCount;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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 GetSystemTimeTCPProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (GetSystemTimeInputStruct) message;
return Format(r_message.Tag, r_message.Leng, r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
int tag = ValueHelper.Instance.GetInt(messageBytes, ref flag);
ushort leng = ValueHelper.Instance.GetUShort(messageBytes, ref 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(tag, leng, belongAddress, functionCode, writeByteCount, year, day,
month, hour, second, minute, millisecond);
}
public class GetSystemTimeInputStruct : InputStruct
{
public GetSystemTimeInputStruct(byte belongAddress)
{
Tag = 0;
Leng = 6;
BelongAddress = belongAddress;
FunctionCode = (int) ModbusProtocalReg.GetSystemTime;
StartAddress = 30000;
GetCount = 5;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
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(int tag, ushort leng, byte belongAddress, byte functionCode,
byte writeByteCount, ushort year, byte day, byte month, ushort hour, byte second, byte minute,
ushort millisecond)
{
Tag = tag;
Leng = leng;
BelongAddress = belongAddress;
FunctionCode = functionCode;
WriteByteCount = writeByteCount;
Time = new DateTime(year, month, day, hour, minute, second, millisecond);
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public byte WriteByteCount { get; private set; }
public DateTime Time { get; private set; }
}
}
public class SetSystemTimeTCPProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (SetSystemTimeInputStruct) message;
return Format(r_message.Tag, r_message.Leng, 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)
{
int tag = ValueHelper.Instance.GetInt(messageBytes, ref flag);
ushort leng = ValueHelper.Instance.GetUShort(messageBytes, ref 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(tag, leng, belongAddress, functionCode, startAddress, writeCount);
}
public class SetSystemTimeInputStruct : InputStruct
{
public SetSystemTimeInputStruct(byte belongAddress, DateTime time)
{
Tag = 0;
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;
Leng = 17;
}
public int Tag { get; private set; }
public short Leng { get; private set; }
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(int tag, ushort leng, byte belongAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
Tag = tag;
Leng = leng;
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteCount = writeCount;
}
public int Tag { get; private set; }
public ushort Leng { get; private set; }
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteCount { get; private set; }
}
}
}

View File

@@ -0,0 +1,111 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace ModBus.Net
{
public abstract class ProtocalUnit : IProtocalFormatting
{
public abstract byte[] Format(InputStruct message);
public virtual byte[] Format(params object[] message)
{
return TranslateContent(message);
}
public abstract OutputStruct Unformat(byte[] messageBytes, ref int pos);
/// <summary>
/// </summary>
/// <param name="contents"></param>
/// <returns></returns>
public 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();
}
}
public class InputStruct
{
}
public class OutputStruct
{
}
}

View File

@@ -0,0 +1,297 @@
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 TCPSocket : 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[200000];
private readonly int port;
public int m_errorCount = 0;
public int m_receiveCount = 0;
public int m_sendCount = 0;
private TcpClient m_socketClient;
public TCPSocket(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 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 void Disconnect()
{
lock (this)
{
if (m_socketClient == null)
{
return;
}
try
{
m_socketClient.Close();
AddInfo("client disconnected successfully.");
}
catch (Exception err)
{
AddInfo("client disconnected exception: " + err.Message);
}
finally
{
m_socketClient = null;
}
}
}
private void AddInfo(string message)
{
Console.WriteLine(message);
}
/// <summary>
/// 发送数据,不需要返回任何值
/// </summary>
/// <param name="message">发送的信息</param>
/// <returns>是否发送成功</returns>
public 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 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();
}
}
}
}