Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Сети > принудительный выход из select без таймаута |
Автор: hash_2000 3.2.2011, 08:55 | ||
здравствуйте ! подскажите пожалуйста ктонибудь, как можно сделать принудительный выход из select'а без установленного таймаута, если ни на один из сокетов не пришли данные ... вот например
.. и для того чтобы на этот сокет ожидались данные нужно чтобы select вернул управление, перезаполнил rfd и передал его снова в select пример немного притянут за уши, но примерно описывает ситуацию ... если ктонибудь знает как можно выкрутиться из такой ситуации ? причем охота разобраться именно с функциями winsock без использования всяческих специалезированных библиотек .. заранее благодарен ! |
Автор: Олег2005 3.2.2011, 18:54 |
Вы же поставили таймаут равно 0 - значит функция моментально опросит все наборы сокетов - и вернет управление. Быстрее - никак не получится..... Прервать работу блокирующей функции - если у вас будет сокет с таймаутом - можно наверное только с помощью WSACancelBlockingCall - это старая функция и ею сейчас уже не пользуются - так как работают на асинхронных сокетах... |
Автор: hash_2000 4.2.2011, 06:44 |
если в select в последнем параметре (TIMEVAL*) передать NULL то функция будет вечно ожидать пока с одним из сокетов в массиве чтонибудь не случится .. а вот WSACancelBlockingCall проверю .. спасибо за наводку ![]() |
Автор: Олег2005 4.2.2011, 11:16 |
Нужно не NULL - а обычный 0........ Это две большие разницы..... |
Автор: Artemon 4.2.2011, 14:45 |
#define NULL 0 |
Автор: Alca 4.2.2011, 15:11 | ||||
для указателей как бы используют NULL |
Автор: Олег2005 5.2.2011, 19:46 |
The parameter time-out controls how long the select can take to complete. If time-out is a null pointer, select will block indefinitely until at least one descriptor meets the specified criteria. Otherwise, time-out points to a TIMEVAL structure that specifies the maximum time that select should wait before returning. When select returns, the contents of the TIMEVAL structure are not altered. If TIMEVAL is initialized to {0, 0}, select will return immediately; this is used to poll the state of the selected sockets. If select returns immediately, then the select call is considered nonblocking and the standard assumptions for nonblocking calls apply. For example, the blocking hook will not be called, and Windows Sockets will not yield. Так что написав простой 0 - получаем моментальное срабатывание. |
Автор: hash_2000 7.2.2011, 06:42 |
кстати вот что нашел в мсдн The WSACancelBlockingCall function has been removed in compliance with the Windows Sockets 2 specification, revision 2.2.0. тоесть она не работает с версией 2 сокетов ... я чтото не совсем понимаю, так что получается, во второй версии вообще никак не выйти из блокирующей функции , только что закрыв сокет а мне это какраз таки и не нужно !!! |
Автор: hash_2000 7.2.2011, 10:04 |
если select не связано никак с сокетами то каким тогда способом узнать что в буфер чтения данные пришли ? или вы предлагаете для каждого пользователя создавать отдельный поток , лично мне кажется что это теже не правильно, ведь если приложение будет работать одновременно например с тысячей пользователей, то буде тысяча простаивающих потоков, ну или не простаивающих, или какието из них будут висеть просто в системе а какието нет , все зависит от программы... но всетаки.. а асинхронные сокеты - это имеется ввиду неблокирующие (тогда функция select нужна всеравно ) ? |
Автор: Олег2005 8.2.2011, 13:32 | ||||||
Я не говорил, что select() никак не связан с сокетами. Эта функция вообще предназначена для отслеживания событий ввода/вывода - например нажатие клавиши на консоли можно тоже отслеживать с ее помощью. Я говорил так "ИСПОЛНЕНИЕ функции не связано с сокетами" Сокеты - сами по себе - а функция - сама по себе. И с сокетами работают вообще без селекта очень часто. Просто функция очень помогает в отслеживании событий на уже открытых и работающих сокетах.
Очень часто так и поступают - т.е. на каждого клиента-пользователя - свой поток обработки. Туда тоже в этот поток можно вставить селект - но этого обычно нет смысла делать.....поток должен будет висеть в памяти и работать сколько надо для полного обслуживания клиента - потому как неизвестно, сколько клиент будет висеть на связи. На самом деле - модель - 1 клиент- 1 поток - неважная модель именно по той причине как вы отметили - очень много ресурсов надо. Поэтому для Windows самая популярная модель cетевого I/O на сервере - это IO Completion Port.
select() - это типичная функция Unix, и виндовс только поддерживает ее - причем не в полном объеме (первый параметр игнорируется). В Виндовсе есть свои приемы асинхронной работы - WSAAsyncSelect() или более эффективная для консольного исполнения WSA EventSelect() - и никакого селекта там не надо.....или тот же самый порт завершения..... |