Ejemplo n.º 1
0
 def run(self):
     logger.debug('Запущен процесс - приёмник собщений с сервера.')
     while self.running:
         # Отдыхаем секунду и снова пробуем захватить сокет.
         # если не сделать тут задержку, то отправка может достаточно долго
         # ждать освобождения сокета.
         time.sleep(1)
         with socket_lock:
             try:
                 self.transport.settimeout(0.5)
                 message = get_my_message(self.transport)
             except OSError as err:
                 if err.errno:
                     logger.critical(f'Потеряно соединение с сервером.')
                     self.running = False
                     self.connection_lost.emit()
             # Проблемы с соединением
             except (ConnectionError, ConnectionAbortedError, ConnectionResetError, json.JSONDecodeError, TypeError):
                 logger.debug(f'Потеряно соединение с сервером.')
                 self.running = False
                 self.connection_lost.emit()
             # Если сообщение получено, то вызываем функцию обработчик:
             else:
                 logger.debug(f'Принято сообщение с сервера: {message}')
                 self.process_server_ans(message)
             finally:
                 self.transport.settimeout(5)
Ejemplo n.º 2
0
def user_list_request(sock, username):
    LOGGER.debug(f'Запрос списка известных пользователей {username}')
    req = {ACTION: USERS_REQUEST, TIME: time.time(), ACCOUNT_NAME: username}
    send_message(sock, req)
    ans = get_my_message(sock)
    if RESPONSE in ans and ans[RESPONSE] == 202:
        return ans[LIST_INFO]
    else:
        raise ServerError
Ejemplo n.º 3
0
def contacts_list_request(sock, name):
    LOGGER.debug(f'Запрос контакт листа для пользователся {name}')
    req = {ACTION: GET_CONTACTS, TIME: time.time(), USER: name}
    LOGGER.debug(f'Сформирован запрос {req}')
    send_message(sock, req)
    ans = get_my_message(sock)
    LOGGER.debug(f'Получен ответ {ans}')
    if RESPONSE in ans and ans[RESPONSE] == 202:
        return ans[LIST_INFO]
    else:
        raise ServerError
Ejemplo n.º 4
0
 def remove_contact(self, contact):
     logger.debug(f'Удаление контакта {contact}')
     req = {
         ACTION: REMOVE_CONTACT,
         TIME: time.time(),
         USER: self.username,
         ACCOUNT_NAME: contact
     }
     with socket_lock:
         send_message(self.transport, req)
         self.process_server_ans(get_my_message(self.transport))
Ejemplo n.º 5
0
 def user_list_update(self):
     logger.debug(f'Запрос списка известных пользователей {self.username}')
     req = {
         ACTION: USERS_REQUEST,
         TIME: time.time(),
         ACCOUNT_NAME: self.username
     }
     with socket_lock:
         send_message(self.transport, req)
         ans = get_my_message(self.transport)
     if RESPONSE in ans and ans[RESPONSE] == 202:
         self.database.add_users(ans[LIST_INFO])
     else:
         logger.error('Не удалось обновить список известных пользователей.')
Ejemplo n.º 6
0
def remove_contact(sock, username, contact):
    LOGGER.debug(f'Создание контакта {contact}')
    req = {
        ACTION: REMOVE_CONTACT,
        TIME: time.time(),
        USER: username,
        ACCOUNT_NAME: contact
    }
    send_message(sock, req)
    ans = get_my_message(sock)
    if RESPONSE in ans and ans[RESPONSE] == 200:
        pass
    else:
        raise ServerError('Ошибка удаления клиента')
    print('Удачное удаление')
Ejemplo n.º 7
0
    def send_message(self, to, message):
        message_dict = {
            ACTION: MESSAGE,
            SENDER: self.username,
            DESTINATION: to,
            TIME: time.time(),
            MESSAGE_TEXT: message
        }
        logger.debug(f'Сформирован словарь сообщения: {message_dict}')

        # Необходимо дождаться освобождения сокета для отправки сообщения
        with socket_lock:
            send_message(self.transport, message_dict)
            self.process_server_ans(get_my_message(self.transport))
            logger.info(f'Отправлено сообщение для пользователя {to}')
Ejemplo n.º 8
0
 def contacts_list_update(self):
     logger.debug(f'Запрос контакт листа для пользователся {self.name}')
     req = {
         ACTION: GET_CONTACTS,
         TIME: time.time(),
         USER: self.username
     }
     logger.debug(f'Сформирован запрос {req}')
     with socket_lock:
         send_message(self.transport, req)
         ans = get_my_message(self.transport)
     logger.debug(f'Получен ответ {ans}')
     if RESPONSE in ans and ans[RESPONSE] == 202:
         for contact in ans[LIST_INFO]:
             self.database.add_contact(contact)
     else:
         logger.error('Не удалось обновить список контактов.')
Ejemplo n.º 9
0
    def run(self):
        while True:
            # Отдыхаем секунду и снова пробуем захватить сокет.
            # если не сделать тут задержку, то второй поток может достаточно
            # долго ждать освобождения сокета.
            time.sleep(1)
            with sock_lock:
                try:
                    message = get_my_message(self.sock)

                except IncorrectDataRecivedError:
                    LOGGER.error(
                        f'Не удалось декодировать полученное сообщение.')
                except OSError as err:
                    if err.errno:
                        LOGGER.critical(f'Потеряно соединение с сервером.')
                        break
                except (ConnectionError, ConnectionAbortedError,
                        ConnectionResetError, json.JSONDecodeError):
                    LOGGER.critical(f'Потеряно соединение с сервером.')
                    break
                else:
                    if ACTION in message and message[ACTION] == MESSAGE and SENDER in message and DESTINATION in message \
                            and MESSAGE_TEXT in message and message[DESTINATION] == self.account_name:
                        print(
                            f'\nПолучено сообщение от пользователя {message[SENDER]}:\n{message[MESSAGE_TEXT]}'
                        )
                        # Захватываем работу с базой данных и сохраняем в неё
                        # сообщение
                        with database_lock:
                            try:
                                self.database.save_message(
                                    message[SENDER], self.account_name,
                                    message[MESSAGE_TEXT])
                            except BaseException:
                                LOGGER.error(
                                    'Ошибка взаимодействия с базой данных')

                        LOGGER.info(
                            f'Получено сообщение от пользователя {message[SENDER]}:\n{message[MESSAGE_TEXT]}'
                        )
                    else:
                        LOGGER.error(
                            f'Получено некорректное сообщение с сервера: {message}'
                        )
Ejemplo n.º 10
0
    def connection_init(self, port, ip):
        # Инициализация сокета и сообщение серверу о нашем появлении
        self.transport = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # Таймаут необходим для освобождения сокета.
        self.transport.settimeout(5)

        # Соединяемся, 5 попыток соединения, флаг успеха ставим в True если
        # удалось
        connected = False
        for i in range(2):
            logger.info(f'Попытка подключения №{i + 1}')
            try:
                self.transport.connect((ip, port))
            except (OSError, ConnectionRefusedError):
                pass
            else:
                connected = True
                break
            time.sleep(1)

        # Если соединится не удалось - исключение
        if not connected:
            logger.critical('Не удалось установить соединение с сервером')
            raise ServerError('Не удалось установить соединение с сервером')

        logger.debug('Установлено соединение с сервером')

        # Посылаем серверу приветственное сообщение и получаем ответ что всё
        # нормально или ловим исключение.
        try:
            with socket_lock:
                send_message(self.transport, self.create_presence())
                self.process_server_ans(get_my_message(self.transport))
        except (OSError, json.JSONDecodeError):
            logger.critical('Потеряно соединение с сервером!')
            raise ServerError('Потеряно соединение с сервером!')

        # Раз всё хорошо, сообщение о установке соединения.
        logger.info('Соединение с сервером успешно установлено.')
Ejemplo n.º 11
0
    def run(self):
        global new_connection
        self.init_socket()

        while True:
            # LOGGER.info(f'Waiting for client message')
            try:
                client, client_address = self.sock.accept()
            except OSError:
                pass
            else:
                LOGGER.info(f'Connection to {client_address} established ')
                self.clients.append(client)

            recv_data_lst = []
            send_data_lst = []
            err_lst = []

            try:
                if self.clients:
                    recv_data_lst, send_data_lst, err_lst = select.select(
                        self.clients, self.clients, [], 0)
            except OSError as err:
                LOGGER.error(f'Ошибка работы с сокетами: {err}')

            # принимаем сообщения и если ошибка, исключаем клиента.
            if recv_data_lst:
                for client_with_message in recv_data_lst:
                    try:
                        self.process_client_message(
                            get_my_message(client_with_message),
                            client_with_message)
                    except (OSError):
                        # Ищем клиента в словаре клиентов и удаляем его из него
                        # и  базы подключённых
                        LOGGER.info(
                            f'Клиент {client_with_message.getpeername()} отключился от сервера.'
                        )
                        for name in self.names:
                            if self.names[name] == client_with_message:
                                self.database.user_logout(name)
                                del self.names[name]
                                break
                        self.clients.remove(client_with_message)
                        with conflag_lock:
                            new_connection = True

            # Если есть сообщения, обрабатываем каждое.
            for message in self.messages:
                try:
                    self.process_message(message, send_data_lst)
                except (ConnectionAbortedError, ConnectionError,
                        ConnectionResetError, ConnectionRefusedError):
                    LOGGER.info(
                        f'Связь с клиентом с именем {message[DESTINATION]} была потеряна'
                    )
                    self.clients.remove(self.names[message[DESTINATION]])
                    self.database.user_logout(message[DESTINATION])
                    del self.names[message[DESTINATION]]
                    with conflag_lock:
                        new_connection = True
            self.messages.clear()
Ejemplo n.º 12
0
def main():
    print('Client started')

    server_address, server_port, client_name = get_args()

    if not client_name:
        client_name = input('Введите имя пользователя: ')
    else:
        print(f'Клиентский модуль запущен с именем: {client_name}')

    LOGGER.info(
        f'Запущен клиент с парамертами: адрес сервера: {server_address} , порт: {server_port}, имя пользователя: {client_name}'
    )

    try:
        transport = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        transport.settimeout(DEF_TIMEOUT)

        transport.connect((server_address, server_port))
        send_message(transport, create_presence(client_name))
        answer = process_response_ans(get_my_message(transport))
        LOGGER.info(
            f'Установлено соединение с сервером. Ответ сервера: {answer}')
        print(f'Установлено соединение с сервером.')
    except json.JSONDecodeError:
        LOGGER.error('Не удалось декодировать полученную Json строку.')
        exit(1)
    except ServerError as error:
        LOGGER.error(
            f'При установке соединения сервер вернул ошибку: {error.text}')
        exit(1)
    except ReqFieldMissingError as missing_error:
        LOGGER.error(
            f'В ответе сервера отсутствует необходимое поле {missing_error.missing_field}'
        )
        exit(1)
    except (ConnectionRefusedError, ConnectionError):
        LOGGER.critical(
            f'Не удалось подключиться к серверу {server_address}:{server_port}, конечный компьютер отверг запрос на подключение.'
        )
        exit(1)
    else:

        database = ClientDB(client_name)
        database_load(transport, database, client_name)

        module_sender = ClientSender(client_name, transport, database)
        module_sender.daemon = True
        module_sender.start()
        LOGGER.debug('Запущены процессы')

        module_receiver = ClientReader(client_name, transport, database)
        module_receiver.daemon = True
        module_receiver.start()

        while True:
            time.sleep(1)
            if module_receiver.is_alive() and module_sender.is_alive():
                continue
            break