Неблокирующий сервер Python Sockets с использованием многопоточности - PullRequest
0 голосов
/ 09 мая 2019

Я строю одноранговую библиотеку в Python, используя сокеты TCP и многопоточность для обработки одноранговых соединений. Я хотел бы иметь main.py, который создает экземпляр класса Node, запускает сервер, прослушивающий соединения через порт, а затем вызывает некоторые методы класса.

e.x. main.py

from p2p import Node

a = Node(port=6666)
a.connect("138.197.105.184", 6666)

Поскольку запуск сервера является блокирующим вызовом, я хотел бы запустить его в отдельном потоке, чтобы программа могла продолжать выполнять какие-либо действия (например, подключаться к другим узлам), одновременно прослушивая соединения.

Узел запускает self.startServer, который запускает сервер в потоке. Новые соединения с сервера также обрабатываются в собственном потоке.

p2p.py

def startServer(self):
        start_new_thread(self.startThreadedServer, ())

def startThreadedServer(self):
        while 1: # blocking call
            logging.debug("Waiting for connection")
            conn, addr = self.server.accept()
            logging.debug(conn + " " + addr)
            logging.info('Connected with ' + addr[0] + ':' + str(addr[1]))
            start_new_thread(self.clientThread ,(conn,))

def clientThread(self, conn):
        while True:
            #Receiving from client
            data = conn.recv(1024)
            if is_json(data):
                payload = json.loads(data)
                reply = self.respond(payload)
            if not data:
                break
            conn.sendall(reply)
        conn.close()

Тем не менее, когда сервер работает таким образом, все соединения сокетов завершаются ошибкой.

Когда я запускаю self.startThreadedServer() в качестве сервера, он принимает соединения, но это блокирующий вызов. Не хорошо.

Как я могу запустить сервер и заставить сервер продолжать слушать и принимать соединения в фоновом режиме?

1 Ответ

0 голосов
/ 20 мая 2019

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

Оба узла должны активно прослушивать соединения в цикле while. Для достижения желаемой функциональности вся программа должна быть демонизирована с использованием пакета типа python-daemon.

...