Вопросы по асинх. TCP серверу с пулом потоков (IOCP)
От: acDev Россия  
Дата: 28.01.11 20:43
Оценка:
Сейчаз реализован и используется сервер, в основе которого блокирующие сокеты. Т.е. данные из сети читаются в одном месте (в отдельном потоке), а отсылаются в сеть в любом месте. Каждый подключившийся клиент использует свой отдельной поток. Клиентов стало значительно больше с недавних пор. Поэтому стала задача полностью переделать сервер. Т.е. сделать сервер асинхронным, да и что бы тысячи клиентов обслуживал небольшое количество потоков (пул потоков).
За последние 2 месяца много чего прочитал и узнал нового.
Нашёл на просторах инета грамотную реализацию HTTP сервера на основе IOCP (с пулом потоков).
Вот как он реализован:
1) Принимает соединения через AcceptEx в отдельном потоке AcceptThread, предварительно создав вызвав CreateIoCompletionPort для AcceptSocket'а.
2) Поток WorkThread вызывает GetQueuedCompletionStatus и вызываются соот-щие обработчики (тип события хранится после структуры Overlapped).
3) Когда возникает событие MY_ACCEPT вызываем обработчик чтения из сокета (он же вызывется и при событии MY_READ).
4) В обработчике MY_READ читаем то что пришло из буфера и если получили не всё, то вызывам WSARecv и "ждём" события MY_READ.
5) Наконец то прочитали пакет (запрос) целиком, обработали его, вызываем WSASend (передали в параметры событие MY_WRITE).
6) "Ждём" запуска обработчика MY_WRITE (окончание слития в сеть). Вызываем снова WSARecv что бы замкнуть порочный круг ...

Т.е. эта реализация обеспечивает протокол обмена типа: acceptEx -> получили запрос -> отправили ответ -> ждём запрос...
У меня же протокол совсем не HTTP. У меня клиент может послать пакет серверу и при этом сервер не обязан на него отвечать. Да и сервер посылает клиенту команды, которые не требуют подтверждения.

Вот и не знаю как этот HTTP сервер передалать под мой протокол.

Да и не знаю как в этом сервере из любого другого потока в любой момент времени послать "моментально" данные клиенту.
Да и можно ли использовать один и тот же сокет в разных потоках "одовременно"?
Обязательно ли дожидаться окончания выполнения WSASend что бы вызвать WSARecv? И наоборот?

Ещё читал что, перекрытый ввод-вывод лучше подходит для обмена в режиме "запрос-ответ" (HTTP сервер). Т.е. в моём случае, когда инициатором может выступать и сервер, лучше какую "конструкцию" сервера выбрать?
Может стоит посмотреть в сторону перекрытого ввод-вывода, реализованого через Event'ы ?
сервер iocp completionport socket wsarecv wsasend acceptex пул потоков асинхронный сервер
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.