Closed JonasNorling closed 1 year ago
If it only sends extra bytes from time to time, the automatic reconnect clears the buffer (in both client and server) so that works until next time the client receives trash bytes.
Try to test with dev, because we added code recently (not released) to solve a similar problem (server on multi drop line), and I expect it to solve your problem as well. It will be released early next month as version 3.3
I will try to make a test case with your example and see if I can statically reproduce it and if so solve it.
The buffer does not get bigger and bigger: This causes the exception (which is a real bug): ´´´ 2023-05-24 09:17:48,466 DEBUG logging:102 recv: 0x0 0x4 0x0 0x0 0x0 0x5 0x0 0x3 0xa 0x0 0x4 2023-05-24 09:17:48,466 DEBUG logging:102 Processing: 0x0 0x4 0x0 0x0 0x0 0x5 0x0 0x3 0xa 0x0 0x4 ´´´ After reconnect, a request is sent and the response is: ´´´ 2023-05-24 09:17:48,872 DEBUG logging:102 recv: 0x0 0x6 0x0 0x0 0x0 0x5 0x0 0x3 0x2 0x0 0x6 2023-05-24 09:17:48,872 DEBUG logging:102 Processing: 0x0 0x6 0x0 0x0 0x0 0x5 0x0 0x3 0x2 0x0 0x6 ´´´ As you can see "Processing" have nothing in common. The problem is that your device sends a faulty response again after the reconnect.
Let me see what I can do to cure the faulty response.
Thanks! PR #1547 fixes the problem, by clearing the framer buffer on decode error. I gave the dev branch a quick try on my device as well, and it looks fine.
I have a modbus server that occasionally returns an invalid response to read-holding-registers, where the "number of bytes" number in the PDU is higher than the actual number of bytes in the response. AsyncModbusTcpClient reacts by disconnecting — which is fine — but after automatically reconnecting it is unable to handle further responses.
From what I can see: ReadRegistersResponseBase.decode() crashes in struct.unpack due to lack of data, because the length indication in the packet was incorrect. This exception isn't caught anywhere and the connection is closed. Upon reconnection, the ModbusSocketFramer is not reset, so when the next response comes in we try to parse the old broken response again. This repeats forever, the framer buffer getting larger every time.
Python: 3.10.9 (also tested 3.9.16) OS: Linux Pymodbus: 3.2.2 (also tested dev2.x-543-gd347bc8)
Code and Logs
Reproducer client
Reproducer server
Log