Вопрос о Клиентах-Серверах на TCP.

Тема в разделе "WASM.BEGINNERS", создана пользователем mituhin, 5 дек 2006.

  1. mituhin

    mituhin New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    6
    Здравствуйте.

    У меня есть клиент-сервер работающий на TCP через сокеты. Есть такая возможность - запускаем один сервер, а затем при помощи нитей можем обслуживать сколько угодно клиентов. При подключении каждого клиента на сервере выводится ID этой нити.

    У меня вопрос - мне нужно реализовать на сервере такую вещь: возможность в любой момент написать /quit ID - т.о. разрывается соединение с конкретным клиентом. Не совсем получается у меня. Подскажите пожалуйста, как лучше это сделать.

    Сам клиент-сервер лежит здесь http://moby.hostex.no/cs.zip (сделал минимальным - отправка логина и пароля, а сервер просто их принимает). Оба работают при запуске на localhost'е.

    Буду ждать помощи. Все заранее спасибо.
     
  2. 10_Brasil

    10_Brasil New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    54
    Напиши функции для работы с связным списком(добавление структуры, удаление, перечисление, поиск и тд), в самом связном списке храни все ID активных подключений, и тут 2 варианта:
    1. ч-з удаления потока (но это не совсем корректно, т.к. нужно очищать ресурсы)
    2. ч-з событие, этот вариант мне кажется более надежный, для этого смотри статьи на тему синхронизация потоков
     
  3. SnugForce

    SnugForce New Member

    Публикаций:
    0
    Регистрация:
    2 май 2005
    Сообщения:
    373
    Адрес:
    Из домУ
    Через событие нельзя, если сокеты блокирующие. Просто для нужного клинта закрывать сокет, а нитка уже дальше обработает ошибку и освободит все данные.
     
  4. TheRawGod

    TheRawGod New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    71
    10_Brasil,
    только я бы скорее остановился на контейнере с ассоциативным доступом (std::map проще всего, пожалуй), нежели на списке, но это не так важно.

    mituhin,
    в остальном Вам уже отлично подсказали, в моем исполнении я бы поступил так:
    если сокеты блокирующие, то надо в этом контейнере хранить соответствие "ID потока -> дескриптор сокета".

    Если сокеты неблокирующие, то либо точно так же, либо событием, как Вам и посоветовали, только в этом случае контейнер будет содержать "ID потока -> ивент".

    Заметьте, что при достаточном количестве клиентов выделять по одному рабочему потоку на каждое активное соединение слишком дорого. В таких случаях, как вариант, сокеты делаются неблокирующими и каждый рабочий поток манипулирует неким списком сокетов, обрабатывая каждый из них по очереди.
     
  5. SnugForce

    SnugForce New Member

    Публикаций:
    0
    Регистрация:
    2 май 2005
    Сообщения:
    373
    Адрес:
    Из домУ
    TheRawGod
    Тогда уж нужно юзать порты завершения. Весч очень классная! Обрабатывай хоть одним потоком. У меня 500 клиентов так висело, пока их сервер не поотключал, чтоб самому не упасть )))
     
  6. mituhin

    mituhin New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    6
    Да я не настолько хорошо С++ знаю. Я просто храню ID в массиве тупо и потом уже при вырубании сокета i'й удаляю. Задача для универа. Больше 3 клиентов и не надо. Но я уже разобрался. ВСЕМ СПАСИБО.
     
  7. TheRawGod

    TheRawGod New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    71
    SnugForce
    Не вопрос, согласен, можно и completion port'ы! :)

    Я про их организацию изнутри подробно не знаю, но интуитивно полагаю, что паттерн там используется подобный 2-му случаю. Ну, идеологически:) Типа менеджер раскидывает таски по рабочим потокам, как только эти самые таски появляются:) Действительно разумно было вынести подобную функциональность на уровень ОС.
    Кстати, под *nix ведь наверняка нет "родных" аналогов completion port'ам? По крайней мере я не сталкивался. Обертки обычно всякие использовались, по крайней мере там, где что-то подобное было нужно.