From e40065168d26fe44c0dcc03c9aced1d7b251f203 Mon Sep 17 00:00:00 2001 From: Bendeguz Kun Date: Mon, 5 Jan 2026 17:35:10 +0100 Subject: [PATCH] Fix transaction identifier colision --- src/FluentModbus/Client/ModbusTcpClient.cs | 12 +++++++++--- .../Client/ModbusTcpClientAsync.cs | 18 ++++++++++++------ .../Resources/ErrorMessage.Designer.cs | 9 +++++++++ src/FluentModbus/Resources/ErrorMessage.resx | 3 +++ 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/FluentModbus/Client/ModbusTcpClient.cs b/src/FluentModbus/Client/ModbusTcpClient.cs index e1cd49c..db38477 100755 --- a/src/FluentModbus/Client/ModbusTcpClient.cs +++ b/src/FluentModbus/Client/ModbusTcpClient.cs @@ -219,16 +219,18 @@ protected override Span TransceiveFrame(byte unitIdentifier, ModbusFunctio writer.Seek(0, SeekOrigin.Begin); + var requestTransactionIdentifier = GetTransactionIdentifier(); + if (BitConverter.IsLittleEndian) { - writer.WriteReverse(GetTransactionIdentifier()); // 00-01 Transaction Identifier + writer.WriteReverse(requestTransactionIdentifier); // 00-01 Transaction Identifier writer.WriteReverse((ushort)0); // 02-03 Protocol Identifier writer.WriteReverse((ushort)(frameLength - 6)); // 04-05 Length } else { - writer.Write(GetTransactionIdentifier()); // 00-01 Transaction Identifier + writer.Write(requestTransactionIdentifier); // 00-01 Transaction Identifier writer.Write((ushort)0); // 02-03 Protocol Identifier writer.Write((ushort)(frameLength - 6)); // 04-05 Length } @@ -291,7 +293,11 @@ protected override Span TransceiveFrame(byte unitIdentifier, ModbusFunctio if (!isParsed) // read MBAP header only once { // read MBAP header - _ = reader.ReadUInt16Reverse(); // 00-01 Transaction Identifier + var responseTransactionIdentifier = reader.ReadUInt16Reverse(); // 00-01 Transaction Identifier + if (requestTransactionIdentifier != responseTransactionIdentifier) + { + throw new ModbusException(ErrorMessage.ModbusClient_InvalidTransactionIdentifier); + } var protocolIdentifier = reader.ReadUInt16Reverse(); // 02-03 Protocol Identifier bytesFollowing = reader.ReadUInt16Reverse(); // 04-05 Length _ = reader.ReadByte(); // 06 Unit Identifier diff --git a/src/FluentModbus/Client/ModbusTcpClientAsync.cs b/src/FluentModbus/Client/ModbusTcpClientAsync.cs index eb89741..aaf0c59 100755 --- a/src/FluentModbus/Client/ModbusTcpClientAsync.cs +++ b/src/FluentModbus/Client/ModbusTcpClientAsync.cs @@ -15,7 +15,7 @@ protected override async Task> TransceiveFrameAsync(byte unitIdenti var frameBuffer = _frameBuffer; var writer = _frameBuffer.Writer; var reader = _frameBuffer.Reader; - + // build request writer.Seek(7, SeekOrigin.Begin); extendFrame(writer); @@ -23,16 +23,18 @@ protected override async Task> TransceiveFrameAsync(byte unitIdenti writer.Seek(0, SeekOrigin.Begin); + var requestTransactionIdentifier = GetTransactionIdentifier(); + if (BitConverter.IsLittleEndian) { - writer.WriteReverse(GetTransactionIdentifier()); // 00-01 Transaction Identifier + writer.WriteReverse(requestTransactionIdentifier); // 00-01 Transaction Identifier writer.WriteReverse((ushort)0); // 02-03 Protocol Identifier writer.WriteReverse((ushort)(frameLength - 6)); // 04-05 Length } else { - writer.Write(GetTransactionIdentifier()); // 00-01 Transaction Identifier + writer.Write(requestTransactionIdentifier); // 00-01 Transaction Identifier writer.Write((ushort)0); // 02-03 Protocol Identifier writer.Write((ushort)(frameLength - 6)); // 04-05 Length } @@ -95,10 +97,14 @@ protected override async Task> TransceiveFrameAsync(byte unitIdenti if (!isParsed) // read MBAP header only once { // read MBAP header - _ = reader.ReadUInt16Reverse(); // 00-01 Transaction Identifier + var responseTransactionIdentifier = reader.ReadUInt16Reverse(); // 00-01 Transaction Identifier + if (requestTransactionIdentifier != responseTransactionIdentifier) + { + throw new ModbusException(ErrorMessage.ModbusClient_InvalidTransactionIdentifier); + } var protocolIdentifier = reader.ReadUInt16Reverse(); // 02-03 Protocol Identifier - bytesFollowing = reader.ReadUInt16Reverse(); // 04-05 Length - _ = reader.ReadByte(); // 06 Unit Identifier + bytesFollowing = reader.ReadUInt16Reverse(); // 04-05 Length + _ = reader.ReadByte(); // 06 Unit Identifier if (protocolIdentifier != 0) throw new ModbusException(ErrorMessage.ModbusClient_InvalidProtocolIdentifier); diff --git a/src/FluentModbus/Resources/ErrorMessage.Designer.cs b/src/FluentModbus/Resources/ErrorMessage.Designer.cs index 63b704f..ff80c2a 100644 --- a/src/FluentModbus/Resources/ErrorMessage.Designer.cs +++ b/src/FluentModbus/Resources/ErrorMessage.Designer.cs @@ -240,6 +240,15 @@ internal static string ModbusClient_InvalidResponseMessageLength { } } + /// + /// Looks up a localized string similar to The transaction identifier is invalid.. + /// + internal static string ModbusClient_InvalidTransactionIdentifier { + get { + return ResourceManager.GetString("ModbusClient_InvalidTransactionIdentifier", resourceCulture); + } + } + /// /// Looks up a localized string similar to The unit identifier is invalid. Valid node addresses are in the range of 0 - 247. Use address '0' to broadcast write command to all available servers.. /// diff --git a/src/FluentModbus/Resources/ErrorMessage.resx b/src/FluentModbus/Resources/ErrorMessage.resx index a6cdfcb..aee2e73 100644 --- a/src/FluentModbus/Resources/ErrorMessage.resx +++ b/src/FluentModbus/Resources/ErrorMessage.resx @@ -165,6 +165,9 @@ The protocol identifier is invalid. + + The transaction identifier is invalid. + The responsed function code is invalid.