Pymodbus останавливает асинхронный TCP-сервер. Повторный запуск кода дает OSError: [Errno 48] Адрес уже используется.
Я работаю с использованием асинхронного TCP-сервера модуля Pymodbus python. Я пытаюсь остановить сервер по мере необходимости, а затем перезапустить, используя тот же порт. Я могу остановить сервер с помощью функции StopServer в модуле Pymodbus; Однако, когда я перезапускаю сервер, я получаю уже используемый адрес [Errno 48].
В моем коде я запускаю сервер в отдельном потоке, и у меня есть команда StopServer в except (KeyboardInterrupt, SystemExit):
Как только я вручную остановлю код python. сервер остановлен и выйдите из кода. Теперь, когда я снова запускаю код, кажется, что порт все еще используется, хотя я остановил сервер. Вопрос в том, как повторно использовать порт? Насколько я понимаю, последняя версия Pymodbus позволяет повторно использовать порт, но в моем случае этого не происходит.
Ниже приведен код, основанный на примере асинхронного сервера PyModbus, доступном в github.
from pymodbus.server.asynchronous import StartTcpServer, StopServer
from pymodbus.server.asynchronous import StartUdpServer
from pymodbus.server.asynchronous import StartSerialServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
from pymodbus.transaction import (ModbusRtuFramer,
ModbusAsciiFramer,
ModbusBinaryFramer)
import threading
from custom_message import CustomModbusRequest
import time
import sys
# --------------------------------------------------------------------------- #
# configure the service logging
# --------------------------------------------------------------------------- #
import logging
FORMAT = ('%(asctime)-15s %(threadName)-15s'
' %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)
def run_async_server():
store = ModbusSlaveContext(
di=ModbusSequentialDataBlock(0, [17]*100),
co=ModbusSequentialDataBlock(0, [17]*100),
hr=ModbusSequentialDataBlock(0, [17]*100),
ir=ModbusSequentialDataBlock(0, [17]*100))
store.register(CustomModbusRequest.function_code, 'cm',
ModbusSequentialDataBlock(0, [17] * 100))
context = ModbusServerContext(slaves=store, single=True)
# ----------------------------------------------------------------------- #
# initialize the server information
# ----------------------------------------------------------------------- #
# If you don't set this or any fields, they are defaulted to empty strings.
# ----------------------------------------------------------------------- #
identity = ModbusDeviceIdentification()
identity.VendorName = 'Pymodbus'
identity.ProductCode = 'PM'
identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
identity.ProductName = 'Pymodbus Server'
identity.ModelName = 'Pymodbus Server'
identity.MajorMinorRevision = '2.3.0'
# ----------------------------------------------------------------------- #
# run the server you want
# ----------------------------------------------------------------------- #
# TCP Server
StartTcpServer(context, identity=identity, address=("xxx.xxx.x.xx", 2040),
custom_functions=[CustomModbusRequest])
if __name__ == "__main__":
x = threading.Thread(target=run_async_server, args=())
try:
x.start()
except OSError as err:
print("error is")
print(err)
x.start()
y = 0
while True:
try:
if y==0: print("Started")
y = y+1
except (KeyboardInterrupt, SystemExit):
StopServer()
time.sleep(2)
sys.exit(0)