Привет, народ ! Встала такай задача: надо написать очень простой сервер на Win32, который будет стоять на некой локальной сети и пересылать IP пакеты с одного хоста на другой, в зависимости от IP порта и содержимого принятого пакета. Никаких DNS, proxy, firewall, login, password и т.д. не требуется. Хостов может быть до тысячи, они ВСЕ и ВСЕГДА сконфигурированы как CLIENT, кроме одного, того самого СЕРВЕРА, который предстоит написать. Софт для SERVER на один CLIENT мною уже написан, оттестирован и работает вполне нормально. Сделать то же самое, скажем, на 5 CLIENTS труда тоже не представляет: вместо одного SOCKET обьявляем 5 и запускаем 5 THREADS, каждая из которых будет слушать и обслуживать свой SOCKET. Ну вот что делать, если будет тысяча CLIENTS ? Интересует чисто структура софта: разделить его на несколько процессов, сколько THREADS и SOCKETS выделить на процесс для обеспечения оптимальной работы или вообше что-то другое надо делать ?
Обычно треды создаются по мере подключения новых клиентов, т.е. примерно так: 1. Сервер-сокет тихо сидит, приложив ухо к сети. 2. Поступил реквест на соединение. 3. Сервер-сокет может отказать или принять реквест, т.е. accept. Обычно он смотрит на количество активных соединений и, если их очень много, то вежливо отказывает. 4. Если реквест принимается, то создаётся новый сокет для обслуживания клиента (этот сокет создаёт accept). Пересылка данных через новый сокет осуществляется в отдельном треде, чтоб сервер-сокет смог продолжить ожидание новых реквестов. 5. goto 1 Для осуществления п.4 есть 2 варианта: 1. Создавать треды по мере подключения клиентов. 2. Заранее создать много тредов (thread pool) чтоб не терять время на создание треда в момент коннекта. Второй вариант сложнее и оправдывается его использование только в экстремальных ситуациях, когда количество соединений в единицу времени очень велико. И они все одновременно будут насиловать сервер? Кстати, создать пул из 1000 тредов на win32 идея не ахти...
Когда будешь выполнять п.1 обрати внимание на listen у него SOMAXCONN=5(очередь одновременных запросов), тебе его лучше увеличить до 10 (для неблокирующего сокета), иначе может быть pending запросов. Можно сделать красивее, если сделать очередь из 10 потоков в "спячке" как только сделан accept стартует трэд и отрабатывает свое дело, при завершении смотрит очередь, если там меньше 10 потоков, то вставляет свой хендл в очередь, если все треды использованы, то сервер создает новые. Если больше 10, то ExitThread. Т.о. у тебы будет некий порог, на случай одновременного зпроса на подключение Это порог подстроишь на месте.
Эх, встала задачка на мультимноговопотоковость, я вот в своей реализации такого сервера не использую много тредов хватает нескольких. создать пул из 1000 тредов на win32 идея не ахти... М-да, задача не такая простая, клиенты должны быть настроены на возможные ошибки и т.д.
Спасибо всем откликнувшимся на эту тему. P.S. А всё-таки, если срочно надо будет сервак написать не на 1000 клиентов, а на несколько десятков, сколько пар sockets - threads можно будет в один процесс загнать, чтобы они крутились в параллель ? Кто-нить экспериментировал ?
Sokol_2 мне почему-то кажется что в таком разрезе это не разрешено даже у Апачи. Может стоит юзать пассивное соединение? Чтобы активных было меньше?
Знаем такое дело. Проходили. Могу посоветовать воспользоваться NSPR. Там уже есть готовая реализаций thread pool + куча готовых примеров в каталоге /pr/test