Example #1
0
def user_controls_cmd(sock, user_name):
    """
    Обработчик поступающих команд от клиента
    :param sock: клиентский сокет
    :param user_name: имя текущего клиента
    :return:
    """
    print(
        'Команда \'message\' для ввода и отправки сообщения, \'exit\' для завершения работы: '
    )

    while True:
        command = input(
            'Введите команду (m - написать сообщение, q - закрыть): ')
        if command == 'm':
            create_client_msg(sock, user_name)
        elif command == 'q':
            send_message(sock, create_exit_message(user_name))
            CLIENT_LOGGER.info('Завершение работы по команде пользователя')
            print('*** Завершение работы ***')
            time.sleep(0.5)
            break
        else:
            print(
                'Команда не распознана, попробуйте снова. \n'
                'Команда \'message\' для ввода и отправки сообщения, \'exit\' для завершения работы: '
            )
def main():
    client = socket(AF_INET, SOCK_STREAM)
    try:
        addr = sys.argv[1]
    except IndexError:
        CLIENT_LOGGER.warning("Нет адреса сервера")
        addr = 'localhost'
    try:
        port = int(sys.argv[2])
    except IndexError:
        CLIENT_LOGGER.warning("Выбран стандарный порт: 7777")
        port = 7777
    except ValueError:
        CLIENT_LOGGER.error("Порт должен быть целым числом")
        client.close()
        sys.exit(0)
    CLIENT_LOGGER.debug("1. Соединение")
    client.connect((addr, port))
    message = create_presence()
    CLIENT_LOGGER.debug("2. Отправка сообщения")
    send_message(client, message)
    CLIENT_LOGGER.debug("3. Ожидание ответа")
    response = get_message(client)
    response = translate_message(response)
    print(response)
    CLIENT_LOGGER.info('Response: ' + str(response))
    client.close()
Example #3
0
def create_client_msg(sock, account_name):
    """
    Формирование и отправка на сервер сообщения клиента
    :param sock: клиентский сокет
    :param account_name: строка псевдонима
    :return message_dict: словарь сообщения клиента
    """

    receiver_name = input('Введите получателя сообщения: ')
    message_str = input('Введите сообщение для отправки: ')

    message_dict = {
        ACTION: MESSAGE,
        TIME: time.time(),
        FROM: account_name,
        TO: receiver_name,
        MESSAGE_TEXT: message_str
    }

    CLIENT_LOGGER.debug(f'Сформировано сообщение: {message_dict}')

    try:
        send_message(sock, message_dict)
        CLIENT_LOGGER.info(
            f'Отправлено сообщение для пользователя {receiver_name}')
    except Exception:
        CLIENT_LOGGER.critical('Потеряно соединение с сервером.')
        sys.exit(1)
def main():
    global server
    global client
    server = socket(AF_INET, SOCK_STREAM)
    try:
        addr = sys.argv[1]
    except IndexError:
        addr = '0.0.0.0'

    try:
        port = int(sys.argv[2])
    except IndexError:
        port = 7777
    except ValueError:
        print('Введите целое число')
        sys.exit(0)

    # a.setsockopt(SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
    server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    server.bind((addr, port))
    server.listen(1)
    while True:
        client, addr = server.accept()
        message = get_message(client)
        print(message)
        response = server_response(message)
        send_message(client, response)
        client.close()
Example #5
0
def main():
    global server
    global client
    server = socket(AF_INET, SOCK_STREAM)
    try:
        addr = sys.argv[1]
    except IndexError:
        SERVER_LOGGER.warning("Нет адреса, использован стандартный")
        addr = ''

    try:
        port = int(sys.argv[2])
    except IndexError:
        SERVER_LOGGER.warning("Выбран стандарный порт: 7777")
        port = 7777
    except ValueError:
        SERVER_LOGGER.warning("Порт должен быть целым числом")
        sys.exit(0)

    # a.setsockopt(SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
    server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    server.bind((addr, port))
    server.listen(1)
    while True:
        client, addr = server.accept()
        SERVER_LOGGER.debug("1. Подтверждение")
        message = get_message(client)
        SERVER_LOGGER.debug("2. Получение сообщения")
        print(message)
        SERVER_LOGGER.info('Message: ' + str(message))
        response = server_response(message)
        SERVER_LOGGER.debug("3. Отправка ответа")
        send_message(client, response)
        client.close()
Example #6
0
def write_responses(messages, w_clients, all_clients):
    for sock in w_clients:
        for message in messages:
            try:
                response = server_response(message)
                send_message(sock, response)
            except:
                print('Client {} {} disconnected'.format(
                    sock.fileno(), sock.getpeername()))
                sock.close()
                all_clients.remove(sock)
def main():
    client = socket(AF_INET, SOCK_STREAM)
    try:
        addr = sys.argv[1]
    except IndexError:
        CLIENT_LOGGER.warning("Нет адреса сервера")
        addr = 'localhost'
    try:
        port = int(sys.argv[2])
    except IndexError:
        CLIENT_LOGGER.warning("Выбран стандарный порт: 7777")
        port = 7777
    except ValueError:
        CLIENT_LOGGER.error("Порт должен быть целым числом")
        client.close()
        sys.exit(0)

    try:
        mode = sys.argv[3]
    except IndexError:
        mode = 'r'
    CLIENT_LOGGER.debug("Начало соединения")
    client.connect((addr, port))
    message = create_message()
    send_message(client, message)
    CLIENT_LOGGER.debug("Ожидание ответа")
    response = get_message(client)
    response = translate_message(response)
    print(f'Установлено соединение с сервером.')
    CLIENT_LOGGER.info('Ответ: ' + str(response))
    if response['response'] == OK:
        if mode == 'r':
            read_messages(client)
        elif mode == 'w':
            write_messages(client)
        else:
            raise Exception("Invalid mode")
    # Старый код
    # CLIENT_LOGGER.debug("1. Соединение")
    # client.connect((addr, port))
    # message = create_message()
    # CLIENT_LOGGER.debug("2. Отправка сообщения")
    # send_message(client, message)
    # CLIENT_LOGGER.debug("3. Ожидание ответа")
    # response = get_message(client)
    # response = translate_message(response)
    # print(response)
    # CLIENT_LOGGER.info('Response: ' + str(response))
    client.close()
def route_client_msg(message, names, clients):
    """
    Адресная отправка сообщений.
    :param message: словарь сообщения
    :param names: список зарегистрированных клиентов
    :param clients: список слушающих клиентских сокетов
    :return:
    """
    if message[DESTINATION] in names and names[message[DESTINATION]] in clients:
        send_message(names[message[DESTINATION]], message)
        SERVER_LOGGER.info(f'Отправлено сообщение пользователю {message[DESTINATION]} '
                           f'от пользователя {message[SENDER]}.')
    elif message[DESTINATION] in names and names[message[DESTINATION]] not in clients:
        raise ConnectionError
    else:
        SERVER_LOGGER.error(
            f'Пользователь {message[DESTINATION]} не зарегистрирован на сервере, '
            f'отправка сообщения невозможна.')
Example #9
0
def main():
    client = socket(AF_INET, SOCK_STREAM)
    try:
        addr = sys.argv[1]
    except IndexError:
        addr = 'localhost'
    try:
        port = int(sys.argv[2])
    except IndexError:
        port = 7777
    except ValueError:
        print('Введите целое число')
        client.close()
        sys.exit(0)
    client.connect((addr, port))
    message = create_presence()
    send_message(client, message)
    response = get_message(client)
    response = translate_message(response)
    print(response)
    client.close()
def parse_client_msg(message, messages_list, sock, clients_list, names):
    """
    обработчик сообщений клиентов
    :param message: словарь сообщения
    :param messages_list: список сообщений
    :param sock: клиентский сокет
    :param clients_list: список клиентских сокетов
    :param names: список зарегистрированных клиентов
    :return: словарь ответа
    """
    SERVER_LOGGER.debug(f'Разбор сообщения от клиента: {message}')
    print(f'Разбор сообщения от клиента: {message}')

    # возвращает сообщение о присутствии
    if ACTION in message and \
            message[ACTION] == PRESENCE and \
            TIME in message and \
            USER in message:

        # авторизация
        if message[USER][ACCOUNT_NAME] not in names.keys():
            names[message[USER][ACCOUNT_NAME]] = sock
            send_message(sock, RESPONSE_200)
        else:
            response = RESPONSE_400
            response[ERROR] = 'Имя пользователя уже занято.'
            send_message(sock, response)
            clients_list.remove(sock)
            sock.close()
        return

    # формирует очередь сообщений
    elif ACTION in message and \
            message[ACTION] == MESSAGE and \
            SENDER in message and \
            DESTINATION in message and \
            MESSAGE_TEXT in message and \
            TIME in message:
        messages_list.append(message)
        return

    # выход клиента
    elif ACTION in message and \
            message[ACTION] == EXIT and \
            ACCOUNT_NAME in message:
        clients_list.remove(names[message[USER][ACCOUNT_NAME]])
        names[message[USER][ACCOUNT_NAME]].close()
        del names[message[USER][ACCOUNT_NAME]]
        return

    # возвращает сообщение об ошибке
    else:
        response = RESPONSE_400
        response[ERROR] = 'Некорректный запрос.'
        send_message(sock, response)
        return
def write_messages(client):
    while True:
        message = create_message()
        CLIENT_LOGGER.debug("Отправка сообщения")
        send_message(client, message)
Example #12
0
def main():
    # Запуск программы
    print('Консольный месседжер. Клиентский модуль.')

    # Получает ip-адрес, порт сервера, режим клиента из командной строки
    server_addr, server_port, client_name = parse_cmd_arguments()

    if not client_name:
        client_name = input('Введите имя пользователя: ')

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

    # Начало работы, приветственное сообщение
    try:
        # Создается TCP-сокет клиента
        client_tcp = socket(AF_INET, SOCK_STREAM)

        # Соединяется с сервером
        client_tcp.connect((server_addr, server_port))

        # Формирует сообщение о присутствии
        presence_msg = create_presence_msg(client_name)

        # Отправляет сообщение о присутствии серверу
        send_message(client_tcp, presence_msg)

        # Получает и разбирает сообщение от сервера
        server_answer = parse_server_msg(client_tcp, client_name)

        CLIENT_LOGGER.info(
            f'Установлено соединение с сервером. Ответ сервера: {server_answer}'
        )
        print(
            f'Установлено соединение с сервером. Ответ сервера: {server_answer}'
        )

    except json.JSONDecodeError:
        CLIENT_LOGGER.error('Не удалось декодировать полученную json-строку')
        print('Не удалось декодировать полученную json-строку')
        sys.exit(1)

    except ConnectionRefusedError:
        CLIENT_LOGGER.critical(
            f'Не удалось подключиться к серверу {server_addr}:{server_port}, '
            f'запрос на подключение отклонён')
        print(
            f'Не удалось подключиться к серверу {server_addr}:{server_port}, '
            f'запрос на подключение отклонён')

    # Обмен сообщениями
    else:
        # Запускает клиентский процесс приёма сообщений
        print('** Запуск потока \'thread_1\' для приёма сообщений **')
        receiver = threading.Thread(target=parse_server_msg,
                                    args=(client_tcp, client_name))
        receiver.daemon = True
        receiver.start()

        # Запускает отправку сообщений и взаимодействие с клиентом
        print('** Запуск потока \'thread_2\' для отправки сообщений **')
        user_interface = threading.Thread(target=user_controls_cmd,
                                          args=(client_tcp, client_name))
        user_interface.daemon = True
        user_interface.start()

        CLIENT_LOGGER.debug('** Процессы запущены **')

        # Watchdog основной цикл, если один из потоков завершён,
        # то значит потеряно соединение или пользователь ввёл exit.
        # Поскольку все события обрабатываются в потоках,
        # достаточно завершить цикл.
        while True:
            time.sleep(1)
            if receiver.is_alive() and user_interface.is_alive():
                continue
            break