Pymodbus stop asyn c TCP сервер. Повторное выполнение кода дает OSError: [Errno 48] Адрес уже используется - PullRequest
0 голосов
/ 27 марта 2020

Я работаю с использованием модуля Pymodbus python асинхронного TCP-сервера. Я пытаюсь остановить сервер по мере необходимости, а затем перезапустить, используя тот же порт. Я могу остановить сервер, используя функцию StopServer в модуле Pymodbus; Однако когда я перезагружаю сервер, я получаю [Errno 48] Address, который уже используется.

В моем коде я запускаю сервер в отдельном потоке, и у меня есть команда StopServer в исключении (KeyboardInterrupt, SystemExit):

Как только я вручную остановлю код python , сервер остановлен и выйдите из кода. Теперь, когда я снова запускаю код, кажется, что порт все еще используется, хотя я остановил сервер. Вопрос в том, как повторно использовать порт? Насколько я понимаю, последняя версия Pymodbus позволяет повторно использовать порт, хотя в моем случае этого не происходит.

Ниже приведен код, основанный на примере сервера PyModbus asyn c, доступном в 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)
...