Православный взгляд на ИТ
Архив форума
Всегда так бывает, что кто сделает с тщеславием - жди бесславия.
Иоанн (Алексеев), схиигум.

 WinSock
Unknown - 20:15 19.04.2007
Кто-нибудь знает как в соккетах заставить функцию accept не ждать запроса, если его нет, а сразу выходить? И то же самое касается функции recv.

 Re: WinSock
bukvarius - 15:18 24.04.2007
Перевести сокет в non-blocking mode. ioctlsocket (MySocket, FIONBIO, (указатель на int, содержащий ненулевое значение)) . См. MSDN или подобное.

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

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

1. Создаете и bind-дите сокет, предназначенный для прослушивания нужного порта. В блокирующем режиме.

2. Делаете listen. Ваш процесс засыпает.

3. Через энное количество времени к вам стучится клиент. listen возвращает 1 (есть 1 запрос на соединение).

4. Делаете accept (он вернется сразу, поскольку клиентский запрос уже ждет) и вернет новый сокет.

5. Открываете новый поток, который будет рулить вновь созданной сессией. Передаете ему сокет, который возвратил accept.

6. Возвращаетесь к шагу 2.

В сессионном потоке Вы без боязни вызываете send, recv в блокирующем режиме. Всё, что происходит, если для recv пока ничего не поступило, -- сессионный поток просто засыпает. Когда сессия подходит к концу, данный сессионный поток уничтожается.

Это упрощенная схема. Ее можно усложнить обработкой ситуации, когда на шаге 3 возвращается больше одного стучащегося запроса; усложнить контролем ресурсов (не более n сессий одновременно); усложнить возможностью останова самого сервера ("слушающий" сокет запускать также в отдельном потоке, а основной поток оставить для бесперебойной работы окна с кнопкой "Стоп"); и т.д.

Плюс, разумеется, не забывать о всех граблях многопоточных приложений.

Если же решите всё же работать в неблокирующем режиме, то Вам придется возиться с организацией обработки асинхронных событий. Не будете же Вы, в самом деле, тупо вызывать неблокирующий accept в бесконечном цикле -- это загрузит процессор на 100%. Нет, придется сказать что-то вроде "Вот тебе callback, вызови ее, когда появится что-то полезное для accept". Аналогично для recv. То есть, то же многопоточное приложение, но диспетчр потоков реализует не Windows, а Вы :-)


Архив форума