-
Notifications
You must be signed in to change notification settings - Fork 951
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ModbusSocketFramer bug when multiple modbus messages are received in 1 tcp payload #1949
Comments
We have corrected a similar bug, and it is available on dev, however I think I will make a test case with multiple messages as well. Can you please add a debug log, so I can see what is actually received. Most devices do not accept multiple frames on the same socket (one client connection), so what is the practical use case ? |
I have a modbus slave which connects to a modbus master (instead of listening for clients to connect to me, I connect to the TCP server of the master). I changed the hard-coded
|
Something is off here....a slave is pr modbus definition a server that listens and wait for clients to connect to it. It seems you have turned the modbus protocol upside down, that will have a lot of other implications like transaction handling, server/client decoder. |
But anyhow your original statement about a bug in socket_framer, did you try dev as I suggested. |
Yeah, I thought the same at first but the commercial device im trying to communicate with wants the slave to connect to itself so I had to implement a custom method as mentioned above. Haven't tried the dev branch yet, will send an update when available |
Please read the modbus protocol, a slave do not connect....but your device is at the rs485 level below modbus, and in rs485 you have one master (client in modbus) and slaves (server ind modbus). |
I believe incorrect behavior can occur also for "standard" communication - communicating with slave, I send 10 (async) requests at the same time, Wireshark shows standard 1 Modbus response per TCP packet: |
We do not support sending multiple requests in our clients, actually it should not be possible, if you use the standard calls. Each client knows it has exactly 0 or 1 request outstanding, and depends on that information, so getting multiple responses is not supported. |
Anyhow the software should not break down, but log an error. |
Please send the pcap file, then it is easier for me to make a test case. |
Just to be sure we are on the same page when it comes to multiple requests - what I do is something like (artificial example, but I used this line for gathering pcap data): await asyncio.gather(*[client.read_holding_registers(address=x, count=2) for x in range(0, 1000, 100)]) I don't think I am doing any shenanigans with PyModbus API, the aggregation of requests in frame # 23 is done by TCP stack (Win10 x64+ CPython 3.11.6). Because the slave is 3rd party device I can comment only on what I see in Wireshark and seems it sends one response at the time ("1" in the picture): I belive the use case itself (send multiple async requests at once, wait for all responses) is valid - "Several MODBUS transactions can be activated simultaneously on the same TCP Connection." (after "4.2 TCP CONNECTION MANAGEMENT" from https://www.modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf ). Attached please find the anonymized pcap. |
It might be you find it is a valid use case, but pymodbus still do not support it....just as many devices have problems when receiving a second request before responding to the first. This is because most devices actually do not care about the transaction id, but simply maps it into the response. If you want pymodbus to support multiple parallel request, then pull requests are welcome. Please remember if you send 10 requests there are no guarantee that the responses are in the same order. I do agree that pymodbus should not breakdown, and that is a case I will look at. |
Added support (silently, because there are surely corner cases, where it does not work). Added a test case with your gather example, but corrected so it actually controls the functionality. This will be part of v3.6.4 |
Versions
Pymodbus Specific
Description
When receiving multiple modbus frames in a single tcp frame, pymodbus throws an error. This happens cause of a misscalculation.
I fixed the issue by substracting 1 in the length calcuation of the frame in "pymodbus/framer/socket_framer.py" line 99:
This happens cause
self._hsize
andself._header["len"]
have theuid
byte.This doesn't happen when there is only 1 modbus packet inside a TCP frame cause in python
my_list[:length] == my_list[:length+1]
is True.Code and Logs
Added some prints inside the framer funtions to debug
The text was updated successfully, but these errors were encountered: