Fix BUG when receiving splited TCP message#602
Conversation
…ort.js Sometime, the tcpport "on data" event not receive all the message. The rest is received after in a second event call. This commit concat all received message and process a message only when a least 1 full message is in memory.
|
@ciePIC thank you for the pull request 💚 @coderabbitai, please review |
|
The PR description images show the bug and fix clearly:
✅ Actions performedReview triggered.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughTcpPort now accumulates incoming socket data in a persistent Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Socket as Socket<br/>Event
participant TCPPort as TCP Port<br/>Handler
participant Buffer as _clientRcvData<br/>Buffer
participant Parser as Frame<br/>Parser
rect rgba(100, 200, 100, 0.5)
Note over Client,Parser: Buffered receive + parse flow
Client->>Socket: send chunk 1
Socket->>TCPPort: 'data' event
TCPPort->>Buffer: append chunk 1
TCPPort->>Parser: check buffer length
Parser-->>TCPPort: incomplete
TCPPort->>TCPPort: wait for more data
Client->>Socket: send chunk 2
Socket->>TCPPort: 'data' event
TCPPort->>Buffer: append chunk 2
TCPPort->>Parser: check buffer length
Parser-->>TCPPort: complete frame found
TCPPort->>Parser: parse frame
Parser-->>TCPPort: frame extracted
TCPPort->>TCPPort: emit frame
TCPPort->>Buffer: slice consumed bytes
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
ports/tcpport.js (1)
154-163: Consider clearing receive buffer on close.If the TcpPort instance were ever reused after close/reconnect, stale data in
_clientRcvDatacould cause unexpected behavior. Clearing the buffer on close would make the state machine more robust.💡 Optional: Clear buffer on close
this._client.on("close", function(had_error) { if (self.openFlag) { self.openFlag = false; + self._clientRcvData = Buffer.alloc(0); modbusSerialDebug("TCP port: signal close: " + had_error); handleCallback(had_error);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ports/tcpport.js` around lines 154 - 163, When handling the socket "close" in TcpPort, clear the receive buffer to avoid stale data on reconnect: inside the this._client.on("close", function(had_error) { ... }) handler (the block that checks self.openFlag and sets self.openFlag = false, calls handleCallback, emits "close" and removeAllListeners), reset the instance receive buffer _clientRcvData to an empty value (e.g., empty Buffer/string/array consistent with how _clientRcvData is used) so the state machine starts clean on reuse/reconnect.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@ports/tcpport.js`:
- Line 111: In the callback where modbusSerialDebug is called, replace the
incorrect this._clientRcvData reference with the TcpPort instance reference
(self._clientRcvData) because inside function(data) this is the socket
(_client); update the modbusSerialDebug call in that callback to use
self._clientRcvData so the actual receive buffer is logged correctly (look for
the function(data) callback and the modbusSerialDebug invocation).
- Around line 99-100: The ESLint spaced-comment error is caused by the inline
comment on the Buffer initialization; update the initializer for
self._clientRcvData in ports/tcpport.js (the line that sets self._clientRcvData
= Buffer.alloc(0)) to ensure the comment has a space after the // (e.g., change
"//Initialize a variable..." to "// Initialize a variable...") so the linter
passes.
---
Nitpick comments:
In `@ports/tcpport.js`:
- Around line 154-163: When handling the socket "close" in TcpPort, clear the
receive buffer to avoid stale data on reconnect: inside the
this._client.on("close", function(had_error) { ... }) handler (the block that
checks self.openFlag and sets self.openFlag = false, calls handleCallback, emits
"close" and removeAllListeners), reset the instance receive buffer
_clientRcvData to an empty value (e.g., empty Buffer/string/array consistent
with how _clientRcvData is used) so the state machine starts clean on
reuse/reconnect.
Fix Usage of this instead of self Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Fx eslint for comment Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Hi @yaacov, Did you need other thing ? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 7374 🏁 Script executed: Length of output: 11559
However, there are still two
- self._clientRcvData = Buffer.concat([self._clientRcvData, data]);
+ self._clientRcvData = Buffer.concat([self._clientRcvData, data]);
-
+Both are in the You can catch these automatically in the future by running |
|
@ciePIC thank you for the fix |
Mainly
Sometimes modbus TCP message can be splited.
This cause the on "data" function in tcpport is call multiple time but never with full data.
With this fix, all received data are stored in a buffer and message is processed only when the buffer contain enougth data.
The quantity of requested data is simply the size of MBAP + the length of the message (extracted from the MBAP)
The Bug Was & the Fix
Context
I try to read 4 holding register from a device. this device is often spliting message.
The device 4 register is [0, 0, 0, 1]
The BUG
I have added (only for test) a console log in the on "data" function to log received data :


The Fix
I have added (only for test) 2 console log in the on "data" function :
Summary by CodeRabbit