Add Modbus TCP transaction ID.

This commit is contained in:
luosheng
2023-03-28 10:56:21 +08:00
parent 129dd190d3
commit 7da1b7ea2a
3 changed files with 57 additions and 7 deletions

View File

@@ -50,6 +50,9 @@ namespace Modbus.Net.Modbus
/// </summary> /// </summary>
public class ModbusTcpProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend public class ModbusTcpProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend
{ {
private static ushort _sendCount = 0;
private static readonly object _counterLock = new object();
/// <summary> /// <summary>
/// 协议扩展,协议内容发送前调用 /// 协议扩展,协议内容发送前调用
/// </summary> /// </summary>
@@ -57,13 +60,19 @@ namespace Modbus.Net.Modbus
/// <returns>扩展后的协议内容</returns> /// <returns>扩展后的协议内容</returns>
public byte[] BytesExtend(byte[] content) public byte[] BytesExtend(byte[] content)
{ {
//Modbus/Tcp协议扩张前面加6个字节前面4个为0后面两个为协议整体内容的长度 //Modbus/Tcp协议扩张前面加6个字节前面2个为事务编号中间两个为0后面两个为协议整体内容的长度
var newFormat = new byte[6 + content.Length]; var newFormat = new byte[6 + content.Length];
var tag = 0; lock (_counterLock)
{
var transaction = (ushort)(_sendCount % 65536 + 1);
var tag = (ushort)0;
var leng = (ushort)content.Length; var leng = (ushort)content.Length;
Array.Copy(BigEndianValueHelper.Instance.GetBytes(tag), 0, newFormat, 0, 4); Array.Copy(BigEndianValueHelper.Instance.GetBytes(transaction), 0, newFormat, 0, 2);
Array.Copy(BigEndianValueHelper.Instance.GetBytes(tag), 0, newFormat, 2, 2);
Array.Copy(BigEndianValueHelper.Instance.GetBytes(leng), 0, newFormat, 4, 2); Array.Copy(BigEndianValueHelper.Instance.GetBytes(leng), 0, newFormat, 4, 2);
Array.Copy(content, 0, newFormat, 6, content.Length); Array.Copy(content, 0, newFormat, 6, content.Length);
_sendCount++;
}
return newFormat; return newFormat;
} }

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Modbus.Net
{
/// <summary>
/// 匹配控制器,载入队列后直接发送
/// </summary>
public class ModbusTcpMatchDirectlySendController : MatchDirectlySendController
{
/// <inheritdoc />
public ModbusTcpMatchDirectlySendController(ICollection<(int, int)>[] keyMatches,
Func<byte[], int> lengthCalc = null, int? waitingListMaxCount = null) : base(keyMatches,
lengthCalc, waitingListMaxCount)
{
}
/// <inheritdoc />
protected override MessageWaitingDef GetMessageFromWaitingList(byte[] receiveMessage)
{
MessageWaitingDef ans;
if (receiveMessage[0] == 0 && receiveMessage[1] == 0)
{
lock (WaitingMessages)
{
ans = WaitingMessages.FirstOrDefault();
}
}
else
{
var returnKey = GetKeyFromMessage(receiveMessage);
lock (WaitingMessages)
{
ans = WaitingMessages.FirstOrDefault(p => returnKey.HasValue && p.Key == returnKey.Value.Item2);
}
}
return ans;
}
}
}

View File

@@ -23,7 +23,7 @@ namespace Modbus.Net.Modbus
/// <param name="port">端口</param> /// <param name="port">端口</param>
public ModbusTcpProtocolLinker(string ip, int port) : base(ip, port) public ModbusTcpProtocolLinker(string ip, int port) : base(ip, port)
{ {
((IConnectorWithController<byte[], byte[]>)BaseConnector).AddController(new FifoController(int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "FetchSleepTime")), lengthCalc: DuplicateWithCount.GetDuplcateFunc(new List<int> { 4, 5 }, 6), waitingListMaxCount: ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount") != null ? int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount")) : null)); ((IConnectorWithController<byte[], byte[]>)BaseConnector).AddController(new ModbusTcpMatchDirectlySendController(new ICollection<(int, int)>[] { new List<(int, int)> { (0, 0), (1, 1) } }, lengthCalc: DuplicateWithCount.GetDuplcateFunc(new List<int> { 4, 5 }, 6), waitingListMaxCount: ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount") != null ? int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "WaitingListCount")) : null));
} }
/// <summary> /// <summary>