Используя сокеты и потоки, мои клиенты не будут оставаться на связи - PullRequest
0 голосов
/ 13 марта 2020

У меня есть следующий код для моего сервера l oop:

    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind((host, port))
    while True:
        server.listen(1)
        clientsock, clientAddress = server.accept()
        self.total_clients += 1
        self.modules['logger'].log("login", "New connection! => " + str(clientAddress))
        self.clients[self.total_clients] = (Client(clientAddress, clientsock, self.total_clients, self.modules))
        self.clients[self.total_clients].start()

В основном кто-то подключается к сокету, и после этого они помещаются в этот l oop на 2-м и последнем строка (та, которая создает экземпляр класса Client). Класс Client выглядит следующим образом:

class Client(threading.Thread):
    def __init__(self, addr, clientsocket, thread_id, modules):
        threading.Thread.__init__(self)

        self.csocket = clientsocket
        self.addr = addr
        self.thread_id = thread_id
        self.modules = modules

        return

    def run(self):
        while True:
            data = self.csocket.recv(2048)
            if(len(data) > 1):
                data = data.decode()
                if data == 'bye':
                    break
                self.clientLog("Data received: {" + data + "}")
                self.parseCatch(self.modules['parser'].parse(data))
        print ("Client ", clientAddress , " disconnected...")

Итак, я хочу, чтобы программа работала так: клиент подключается к сокету. Затем они помещаются в run () l oop в потоке класса Client на неопределенное время для всего остального, что они отправляют, а l oop отвечает на определенные пакеты (это делается в функции parseCatch (), которой у меня нет включен, так как это просто "если x получил, отправьте y назад").

В любом случае, программа не работает так. Как это работает сейчас, клиент подключается к сокету и помещается в run () l oop в потоке класса Client. Это хорошо, пока. Затем они отправляют определенный пакет, скажем, они посылают "привет". Это получено в 'data' в прогоне l oop в нижнем классе Client, и, скажем, я отвечаю hi на self.csocket.send('hi back');. Это отлично работает. Их клиент получает привет назад. Однако, если они отправляют что-то обратно, например, пока, это рассматривается как совершенно новый клиент.

Так или иначе, когда этот произвольный клиент отвечает на мой пакет, который я отправил в потоке Client (), они рассматриваются как совершенно новое соединение. Так что, если клиент отправляет «привет», сервер отправляет «привет назад», это пока хорошо. Однако, если клиент затем отвечает снова и говорит что-то вроде «пока», он каким-то образом обрабатывается главным сервером l oop в верхнем блоке кода, и я получаю сообщение «Новое соединение! =>». Я не хочу, чтобы клиент обрабатывался в этом l oop, я хочу, чтобы он обрабатывался в собственном существующем ранее потоке.

По какой-то причине, когда клиент отвечает новыми данными, он покидает свой поток. Кажется, что l oop даже не сломан, потому что он никогда не говорит «Клиент отключен».

Пожалуйста, помогите. Спасибо.

...