pymodbus-dev / pymodbus

A full modbus protocol written in python
Other
2.29k stars 937 forks source link

server disconnection not detected from pymodbus client #1239

Closed cyrduf closed 1 year ago

cyrduf commented 1 year ago

Versions

Pymodbus Specific

Description

1/ The pymodbus cannot detect is a server is closed() or down(). I make a test code taht show the is_open_socket return always true if a start a server and then close it

=> how to check with the 3.0.2 a server is down ? because it's a problem. => I cannot update version because the 3.0.2 is to use

=> I have the same problem with the 2.5.3.

2/ a change from 2.5.3 to 3.0.2 to find why it's not ok the client .host and client.port accessible with 2.5.3 are not accessible with 3.0.2. => how to do the same thing with the 3.0.2 : client = ModbusTcpClient(address_clt, port_clt); => client.host getting failed.

Code and Logs

The server : from pyModbusTCP.server import ModbusServer

server = ModbusServer(IP, int(PORT, 10), no_block=True) server.start() server.stop()

The client : from pymodbus.client import ModbusTcpClient if 3.0.2 The client : from pymodbus.client.sync import ModbusTcpClientt if 2.5.3

client = ModbusTcpClient(address_clt, port_clt); client.connect()

while True: print(client.is_socket_open())

janiversen commented 1 year ago

I do not think we have ever documented to use “is_socket_open” and surely not to detect if the client is connected. The needs to be open for the client to connect to the server, so it is open all the time.

As you can see from our examples and documentation for async we do: ´´´ await client.connect() assert client.protocol ´´´ for sync we do: ´´´ self.assertTrue(client.connect()) ´´´ The documentation is there to be read 😄

janiversen commented 1 year ago

Just to be sure I double checked the code, and as I remembered “is_socket_open” only tells if the socket is opened or not.

cyrduf commented 1 year ago

Thank your for your answer, I read the doc and it's not really usefull for me.

Ok “is_socket_open” only tells if the socket is opened or not on client side. But it's the same thing for client.connect() => it's always returning True even if I stop the server side with server.stop()

So my search or my request is : how to detect on client side a disconnection of socket if server closed ? Because no error is given if I call client.connect() after server close.

So how to check this disconnection on client side with actual lib ?

janiversen commented 1 year ago

client.connect() do not always return True in v3.0.2 that is why we use it to test if the server is connected.

There is a big difference between the first connect and anything after that. For the first connect, connect() return true/false.

The client have automatic reconnection, with a timeout, so after the first connect the client is always connected until it reaches the timeout.

For practical applications it is simple to detect if there are a real connection, if the app does not receive a response fast, then it is because the connection was lost (but might come back).

If you absolutely needs to know if the client is connected at a given time, you need to get the socket we use (this will NOT work for serial and UDP types) and check the status (if it is connected). Pymodbus do not offer an API to access the socket.

You are welcome to submit a PR that adds a “is_client_connected()” to pymodbus.

cyrduf commented 1 year ago

Thank you for the answer, it's that I can observe and so I will check how to do while a function such as “is_client_connected()” is not offered in pymodbus. Regards

janiversen commented 1 year ago

Closing issue as solved. Looking forward to see a pull request.