Запустите TCPServer с ThreadingMixIn снова в код сразу после его выключения. (Выдает ʻAddress already in use`)

Я пытаюсь запрограммировать TCPServer с потоками (ThreadingMixIn) в Python. Проблема в том, что я не могу его правильно выключить, так как получаю socket.error: [Errno 48] Адрес уже используется , когда я пытаюсь запустить его снова. Это минимальный пример кода Python, который вызывает проблему:

import socket
import threading
import SocketServer

class FakeNetio230aHandler(SocketServer.BaseRequestHandler):

    def send(self,message):
        self.request.send(message+N_LINE_ENDING)

    def handle(self):
        self.request.send("Hello\n")

class FakeNetio230a(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    def __init__(self, server_address, RequestHandlerClass):
        self.allow_reuse_address = True
        SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)

if __name__ == '__main__':
    for i in range(2):
        fake_server = FakeNetio230a(("", 1234), FakeNetio230aHandler)
        server_thread = threading.Thread(target=fake_server.serve_forever)
        server_thread.setDaemon(True)
        server_thread.start()
        # might add some client connection here
        fake_server.shutdown()

Все, что должен делать основной код, - это запускать сервер, выключите его и запустите снова. Но это вызывает указанную выше ошибку, потому что сокет не был освобожден после первого выключения.

Я думал, что установка self.allow_reuse_address = True может решить проблему, но это не сработало. Когда программа python завершится, я могу сразу же запустить ее снова, и она сможет запустить сервер один раз (но снова не дважды).
Однако проблема исчезает, когда я произвольно выбираю порт (например, заменяю 1234 на 1234 + i ), поскольку никакой другой сервер не прослушивает этот адрес.

Аналогичный SO Q Изящное завершение работы из ThreadingTCPServer , но решение (установить allow_reuse_address на True не работает для моего кода, и я не использую ThreadingTCPServer).

Как мне изменить свой код, чтобы иметь возможность запускать сервер дважды в моем коде?

Дополнительная информация: Причина, по которой я делаю это, заключается в том, что я хочу запустить несколько модульных тестов для моего проекта python . Для этого необходимо предоставить (поддельный) сервер, к которому должно подключаться мое программное обеспечение.

изменить :
Я только что нашел наиболее правильный ответ на свою проблему: мне нужно добавить fake_server.server_close () в конец моего основного кода выполнения (сразу после fake_server.shutdown () ). Я нашел его в исходном файле реализации TCPServer . Все, что он делает, - это self.socket.close () .

5
задан Community 23 May 2017 в 12:07
поделиться