Exemplo n.º 1
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()
Exemplo n.º 2
0
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'отправка сообщения невозможна.')
Exemplo n.º 3
0
def main():
    # извлекает ip-адрес и порт из командной строки
    listen_addr, listen_port = parse_cmd_arguments()

    # создает TCP-сокет сервера
    server_tcp = socket(AF_INET, SOCK_STREAM)

    # связывает сокет с ip-адресом и портом сервера
    server_tcp.bind((listen_addr, listen_port))

    # таймаут для операций с сокетом
    server_tcp.settimeout(0.5)

    # запускает режим прослушивания
    server_tcp.listen(MAX_CONNECTIONS)

    SERVER_LOGGER.info(
        f'Запущен сервер, порт для подключений: {listen_port}, '
        f'адрес с которого принимаются подключения: {listen_addr}. '
        f'Если адрес не указан, принимаются соединения с любых адресов.')

    print(f'Запущен сервер, порт для подключений: {listen_port}, '
          f'адрес с которого принимаются подключения: {listen_addr}.')

    # список клиентов и очередь сообщений
    all_clients = []
    all_messages = []

    # словарь зарегистрированных клиентов: ключ - имя пользователя, значение - сокет
    all_names = dict()

    while True:
        # принимает запрос на соединение
        # возвращает кортеж (новый TCP-сокет клиента, адрес клиента)
        try:
            client_tcp, client_addr = server_tcp.accept()
        except OSError:
            pass
        else:
            SERVER_LOGGER.info(
                f'Установлено соедение с клиентом {client_addr}')
            print(f'Установлено соедение с клиентом {client_addr}')
            all_clients.append(client_tcp)

        r_clients = []
        w_clients = []
        errs = []

        # запрашивает информацию о готовности к вводу, выводу и о наличии
        # исключений для группы дескрипторов сокетов
        try:
            if all_clients:
                r_clients, w_clients, errs = select.select(
                    all_clients, all_clients, [], 0)
        except OSError:
            pass

        # чтение запросов из списка клиентов
        if r_clients:
            for r_sock in r_clients:
                try:
                    parse_client_msg(receive_message(r_sock), all_messages,
                                     r_sock, all_clients, all_names)
                except Exception as ex:
                    SERVER_LOGGER.error(
                        f'Клиент отключился от сервера. '
                        f'Тип исключения: {type(ex).__name__}, аргументы: {ex.args}'
                    )
                    all_clients.remove(r_sock)

        # роутинг сообщений адресатам
        for msg in all_messages:
            try:
                route_client_msg(msg, all_names, w_clients)
            except Exception:
                SERVER_LOGGER.info(
                    f'Связь с клиентом {msg[DESTINATION]} была потеряна')
                all_clients.remove(all_names[msg[DESTINATION]])
                del all_names[msg[DESTINATION]]
        all_messages.clear()
Exemplo n.º 4
0
            messages.append(message)
        except BaseException:
            print('Client {} {} disconnected'.format(sock.fileno(),
                                                     sock.getpeername()))
            all_clients.remove(sock)

    return messages


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)


# Спасибо stackoverflow за эту подсказку
if __name__ == '__main__':
    SERVER_LOGGER.info("Сервер запущен")
    try:
        main()
    except Exception as e:
        SERVER_LOGGER.error("Exception: {}".format(str(e)))
    SERVER_LOGGER.info("Сервер остановлен")