def read_requests(self, r_clients, all_clients): """ Чтение сообщений, которые будут посылать клиенты :param r_clients: клиенты которые могут отправлять сообщения :param all_clients: все клиенты :return: """ # Список входящих сообщений messages = [] for sock in r_clients: try: # Получаем входящие сообщения message = get_message(sock) # Добавляем их в список messages.append((message, sock)) except: # если не можем ответить клиенту, значит он отключился, оповещаем остальных, убираем его из списка all_clients.remove(sock) try: del self.names[self.client_name] except: pass self.serverBD.remFromActive(self.client_name) # Возвращаем словарь сообщений return messages
def start(self, password=None): """ Запуск клиента: :param password: пароль в текстовом виде, из поля для ввода пароля GUI-клиента :return: """ client = socket(AF_INET, SOCK_STREAM) # Создать сокет TCP self.ourSocket = client # подключаемся к серверу self.connectToServer(client, 0) # Формируем сообщение серверу presence = self.create_presence(account_name=self.username, password=password) # Отправляем сообщение серверу send_message(client, presence) # получаем ответ, авторизованы ли мы response = get_message(client) # разбираем ответ response = self.translate_message(response) # если сервер ответил, что нас нет, отправляем ему данные для регистрации if response['response'] == answer.NOT_FOUND.value: self.ourSocket.send(self.password) print('Сервер знает про нас') # проходим аутентификация на сервере self.client_authenticate() # получаем результат аутентификации response = get_message(client) # Разобрать ответ сервера response = self.translate_message(response) # если ответ с кодом 200 (ОК) if response['response'] == answer.OK.value: print("Прошли аутентификацию") self.auth = True # ставим признак того, что пользователь аутентифицирован logger.info(f"{'=' * 10}Успешное подключение{'=' * 10}") self.getAllUsers(client) # запускам вторичный поток, в котором будем ожидать и работать с входящими сообщениями t = threading.Thread(target=self.read_messages, args=(client, )) t.start() # стартуем вторичный поток # в первичном потоке переходим в функцию с бесконечным циклом ввода и отправки сообщений self.write_messages(self.username) else: print("Не прошли аутентификацию") client.close()
def read_messages(self, client): """ Клиент читает входящие сообщения в бесконечном цикле :param client: сокет клиента :return """ # бесконечный цикл, к котором мы постоянно пытаемся принять сообщение while True: # принимаем сообщение message = get_message(client, '') self.res_queue.put((message, '')) self.res_queue.join()
def getAllUsers(self, client): """ Запрос и получения списка контактов из БД сервера :param client: сокет клиента дял отправки сообщения с запросом списка пользователей :return """ # формируем сообщение с запросом списка message = { pctType.ACTION.value: action.GETCONTACT.value, pctType.TIME.value: time.time(), pctType.USER.value: { pctType.ACCOUNT_NAME.value: self.username } } # отправляем сообщение на сервер send_message(client, message) # принимает ответ response = get_message(client, '') # заносим принятые контакты в локальную БД self.clientDB.addContactList(response['alert'], self.username)
def start(self): """ Запуск сервера. Используем модуль select. """ self.server.bind((self.addr, self.port)) # присваиваем полученный порт и хост self.server.listen(self.sercl) # начинаем ждать подключения # Задержка для корректной работы модуля select self.server.settimeout(0.2) # действие ниже будут выполняться циклически и во веки веков logger.info(f"{'=' * 10}Запуск сервера{'=' * 10}") print("Сервер запущен") while True: try: # принимаем запрос на соединение conn, addr = self.server.accept() logger.info(f"{'=' * 10}Начало соединения{'=' * 10}") logger.info(f'Соединение с ip:{addr[0]}, port:{addr[1]}') # принимает сообщение клиента presence = get_message(conn, addr) # определяем ник клиента self.client_name = presence['user']['account_name'] # проверка есть ли такой клиент в нашей БД clientSecretPhrase = self.serverBD.getUserSekretKey(self.client_name) # если нет, запрашиваем у клиента пароль и добавляем в БД if clientSecretPhrase is None: clientSecretPhrase = self.reqPassword(conn) self.serverBD.addNewClient(self.client_name, clientSecretPhrase) # если клиент есть, отправляем ему ОК и следуем дальше else: response = self.presence_response(presence) send_message(conn, response) # аутифицируем клиента if self.server_authenticate(conn, clientSecretPhrase): response = self.auth_response(True) send_message(conn, response) else: response = self.auth_response(False) send_message(conn, response) conn.close() except OSError as e: pass # timeout вышел else: print(f"Получен запрос на соединение от {str(addr)}") self.names[self.client_name] = conn # Добавляем клиента в список self.clients.append(conn) # добавляем ник пользователя в таблицу подлючившихся и выбираем его id self.serverBD.addActiveClientToBD(self.client_name, addr, self.clients) finally: # Проверить наличие событий ввода-вывода wait = 0 r = [] # список клиентов, которые готовы читать w = [] # список клиентов, которые готовы читать try: # получаем клиентов, которые готовы r - читать,w - писать или отвалились с ошибками - e r, w, e = select.select(self.clients, self.clients, [], wait) except: pass # Ничего не делать, если нет подключений (ждем) requests = self.read_requests(r, self.clients) # Получаем сообщения от клиентов self.write_responses(requests) # отправляем сообщения