Skip to content

Commit 01292f8

Browse files
committed
add stop() and is_run to server
1 parent a208058 commit 01292f8

File tree

1 file changed

+56
-21
lines changed

1 file changed

+56
-21
lines changed

pyModbusTCP/server.py

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -221,31 +221,66 @@ def __init__(self, host='localhost', port=const.MODBUS_PORT, no_block=False, ipv
221221
:param ipv6: use ipv6 stack
222222
:type ipv6: bool
223223
"""
224+
# public
224225
self.host = host
225226
self.port = port
226227
self.no_block = no_block
227228
self.ipv6 = ipv6
228-
# set class attribute
229-
ThreadingTCPServer.address_family = socket.AF_INET6 if self.ipv6 else socket.AF_INET
230-
ThreadingTCPServer.daemon_threads = True
231-
# init server
232-
self._service = ThreadingTCPServer((self.host, self.port), self.ModbusService, bind_and_activate=False)
233-
# set socket options
234-
self._service.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
235-
self._service.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
236-
# TODO test no_delay with bench
237-
self._service.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
238-
# add thread for no block mode
239-
if self.no_block:
240-
self._serve_th = Thread(target=self._service.serve_forever)
241-
self._serve_th.daemon = True
229+
# private
230+
self._running = False
231+
self._service = None
232+
self._serve_th = None
242233

243234
def start(self):
244-
# bind and activate
245-
self._service.server_bind()
246-
self._service.server_activate()
247-
# serve request
248-
if self.no_block:
249-
self._serve_th.start()
250-
else:
235+
"""Start the server.
236+
237+
Do nothing is server is already running.
238+
This function will block if no_block is not set to True.
239+
"""
240+
if not self.is_run:
241+
# set class attribute
242+
ThreadingTCPServer.address_family = socket.AF_INET6 if self.ipv6 else socket.AF_INET
243+
ThreadingTCPServer.daemon_threads = True
244+
# init server
245+
self._service = ThreadingTCPServer((self.host, self.port), self.ModbusService, bind_and_activate=False)
246+
# set socket options
247+
self._service.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
248+
self._service.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
249+
# TODO test no_delay with bench
250+
self._service.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
251+
# bind and activate
252+
self._service.server_bind()
253+
self._service.server_activate()
254+
# serve request
255+
if self.no_block:
256+
self._serve_th = Thread(target=self._serve)
257+
self._serve_th.daemon = True
258+
self._serve_th.start()
259+
else:
260+
self._serve()
261+
262+
def stop(self):
263+
"""Stop the server.
264+
265+
Do nothing is server is already not running.
266+
"""
267+
if self.is_run:
268+
self._service.shutdown()
269+
self._service.server_close()
270+
271+
@property
272+
def is_run(self):
273+
"""Return True if server running.
274+
275+
"""
276+
return self._running
277+
278+
def _serve(self):
279+
try:
280+
self._running = True
251281
self._service.serve_forever()
282+
except:
283+
self._service.server_close()
284+
raise
285+
finally:
286+
self._running = False

0 commit comments

Comments
 (0)