Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > select fd_set максимальный размер


Автор: azesmcar 14.4.2009, 11:46
Добрый день,

Чем больше работаю с сокетами - тем больше убеждаюсь что я чего-то не понимаю конкретно smile
функция select принимает параметр - структуру fd_set.

Код

#ifndef FD_SETSIZE
#define FD_SETSIZE      64
#endif /* FD_SETSIZE */

typedef struct fd_set {
        u_int   fd_count;               /* how many are SET? */
        SOCKET  fd_array[FD_SETSIZE];   /* an array of SOCKETs */
} fd_set;

что это? нельзя проверять на события больше 64 сокетов? Это как-то ненормально, в МСДН написано что можно изменить значение FD_SETSIZE перед иклудом - делаю вывод что это нормально - но..на одном форуме прочел что это неправильно, можно найти другое решение, правда не сказано какое..делаю вывод - можно циклом пихать сокеты в fd_set под 64 штуки на итерацию и делать select, но если у меня блокирующий select? Пока первые 64 не выдадут события - на остальных серверу будет наплевать..хмммм, кто что скажет?

Автор: JackYF 14.4.2009, 14:22
Покурил маны, нигде число 64 не увидел.

Автор: azesmcar 14.4.2009, 14:24
JackYF

В манах я тоже не увидел..это студия - код кроссплатформенный

Автор: MAKCim 14.4.2009, 21:15
Цитата(azesmcar @  14.4.2009,  11:46 Найти цитируемый пост)
Это как-то ненормально

вполне нормально

хочешь больше - юзай poll

Автор: azesmcar 14.4.2009, 22:33
Цитата

хочешь больше - юзай poll 

так нету его под виндоуз. Мне нужно кроссплаторменно..
если я сделаю 
#define FD_SETSIZE      1000
перед инклудом это мне напомнят в судный день? Смертных грех или не очень?

Автор: J0ker 15.4.2009, 01:20
курите тщательней
http://support.microsoft.com/kb/111855

Автор: azesmcar 15.4.2009, 08:35
Цитата

курите тщательней

это кому предназначалось? тому кто маны курил? smile
1. маны к мсдн отношения не имеют
2. я сказал что в мсдн нашел, в манах - нет


Автор: Олег2005 15.4.2009, 13:12
Как пишет Р. Стивенс, FD_SETSIZE для большинства юниксподобных систем равно 256.
Простое увеличение через дефайн Стивенс пишет - может не действовать - без перекомпиляции ядра.
Он же пишет - что для кросплатформенности не стоит изменять это значение.

Автор: azesmcar 15.4.2009, 13:14
Олег2005

Замечательно, добавил проблем на мою голову..а решение??? smile

Добавлено через 2 минуты и 52 секунды
Из МСДН
Цитата

Four macros are defined in the header file Winsock2.h for manipulating and checking the descriptor sets. The variable FD_SETSIZE determines the maximum number of descriptors in a set. (The default value of FD_SETSIZE is 64, which can be modified by defining FD_SETSIZE to another value before including Winsock2.h.

вот только я тоже прочел что
Цитата

для кросплатформенности не стоит изменять это значение

так что же делать? Изменять только под виндоуз? Не важно, 256 тоже маловато.
 smile 

Автор: Олег2005 15.4.2009, 13:32
Цитата(azesmcar @  15.4.2009,  12:14 Найти цитируемый пост)
Замечательно, добавил проблем на мою голову..а решение???

Сами эти проблемы высыпали себе на голову.......
А решение? Из двух(трех) зол - выбирать наименьшее.
Увы, всем угодить не получается....

Автор: azesmcar 15.4.2009, 13:38
Цитата

Сами эти проблемы высыпали себе на голову.......

т.е. чем я себе эти проблемы создал? тем что программистом стал или что кроссплатформенный код надо писать? smile
Цитата

А решение? Из двух(трех) зол - выбирать наименьшее.

а которое наименьшее?? мне нужна поддержка обработки ну как минимум 500 сокетов. 

Автор: Олег2005 15.4.2009, 22:04
Цитата(azesmcar @  15.4.2009,  12:38 Найти цитируемый пост)
т.е. чем я себе эти проблемы создал? тем что программистом стал или что кроссплатформенный код надо писать?

Ясно что кроссом....
Для кросса только селект то и подходит - он и там и там есть.
Но в винде есть более мощные модели сетевого I/O - а в никсах - увы.
Или как-то изголяться с
#ifdef windows

#endif 

#ifdef unix

#endif 
Других мыслей нет

Автор: azesmcar 15.4.2009, 22:28
Олег2005

В принципе у меня неблокирующий сокет. Я могу циклом засовывать сокеты в селект по 64 штуки за раз. Как вариант эта методика имеет права на жизнь?

Добавлено через 2 минуты и 19 секунд
Цитата

Но в винде есть более мощные модели сетевого I/O - а в никсах - увы.

В никсах есть poll как сказал MAKCim, но...как сказали вы - увы smile 
Цитата

Ясно что кроссом....

 smile таковы требования, ничего не поделать.

Автор: Олег2005 15.4.2009, 22:48
Цитата(azesmcar @  15.4.2009,  21:28 Найти цитируемый пост)
В принципе у меня неблокирующий сокет. 

Это понятно

Цитата(azesmcar @  15.4.2009,  21:28 Найти цитируемый пост)
Я могу циклом засовывать сокеты в селект по 64 штуки за раз. Как вариант эта методика имеет права на жизнь?

А вот тут я не особенно врубаюсь smile 
Засовывать вы имеет право - FD_SET'ом 64 сокета.
И что это даст?
Поясните свое предположение - алгоритм в двух словах......

Автор: azesmcar 15.4.2009, 23:35
Олег2005

Засовываю 64 сокета. Вызываю селект. Есть события, обрабатываю, нет событий - засовываю еще 64, пока не кончатся. Таймаут на селект ставлю 0.

Автор: vinick 16.4.2009, 11:27
Цитата(azesmcar @  15.4.2009,  23:35 Найти цитируемый пост)

Есть события, обрабатываю, нет событий - засовываю еще 64, пока не кончатся. Таймаут на селект ставлю 0. 
 

Если таймаут 0, то селект будет ждать пока на сокетах не произойдет события.  Так что если нет событий, то другие ты вставить не сможешь.
Если ставить маленький, но реальный, таймаут, то тоже возможны ситуации когда сокет с данными простаивает слишком долго из-за того что он оказался в конце твоей очереди.

Может все-таки лучше использовать другие механизмы, для которых нет ограничения на количество сокетов. А для кросс-платформености использовать готовые  обертки типа boost.asio или ACE или самому написать такую обертку.

Автор: MAKCim 16.4.2009, 11:35
в linux, ребята, есть epoll, а это реально мощная штука  smile 

Автор: azesmcar 16.4.2009, 11:37
Цитата

Если таймаут 0, то селект будет ждать пока на сокетах не произойдет события.  Так что если нет событий, то другие ты вставить не сможешь.

где такое написано? селект блокируется если передать 0 вместо timeout а не если передать структуру с таймаутом 0.

МСДН
Цитата

timeout 
Maximum time for select to wait, provided in the form of a TIMEVAL structure. Set the timeout parameter to null for blocking operations.


Цитата

Может все-таки лучше использовать другие механизмы, для которых нет ограничения на количество сокетов. А для кросс-платформености использовать готовые  обертки типа boost.asio или ACE или самому написать такую обертку.

Так я и пишу обертку. а как ее писать то?

MAKCim
Вы видимо темой ошиблись smile это надо было постить сюда
http://forum.vingrad.ru/forum/topic-248292.html

Я прекрасно знаю что линукс мощная штука...проблема в кроссплатформенности smile 

Автор: vinick 16.4.2009, 11:54
Цитата(azesmcar @  16.4.2009,  11:37 Найти цитируемый пост)
где такое написано? селект блокируется если передать 0 вместо timeout а не если передать структуру с таймаутом 0.

Извиняюсь. я почему-то решил что передаешь именно нулевой указатель.


Цитата(azesmcar @  16.4.2009,  11:37 Найти цитируемый пост)
Так я и пишу обертку. а как ее писать то?


Код

int SuperSelect(SOCKET* fds,...)
{
#ifdef WINDOWS
используем I/O completion ports
#endif
#ifdef  LINUX
используем epoll
#endif
#ifdef FREEBSD
используем kqueue
#endif

По другому наверно никак.

Автор: azesmcar 16.4.2009, 12:00
Цитата

Извиняюсь. я почему-то решил что передаешь именно нулевой указатель.

Ну пока я ничего не передаю smile я думаю что передать


vinick

про "I/O completion ports" если можно подробнее...
кстати, а в БСД что, нет poll, epoll?

Автор: vinick 16.4.2009, 12:16
Цитата(azesmcar @  16.4.2009,  12:00 Найти цитируемый пост)

про "I/O completion ports" если можно подробнее...

я про них знаю только название и то что они являются аналогом epoll в линуксе smile так что лучше в MSDN загляни.

Цитата(azesmcar @  16.4.2009,  12:00 Найти цитируемый пост)
кстати, а в БСД что, нет poll, epoll? 

poll скорее всего есть - это тот же select только в профиль. а вот epoll это чисто линуксовая штучка, ее аналогом в BSD является kqueue.

Подробнее по *nix-вым механизмам можешь посмотреть здесь http://www.kegel.com/c10k.html

Автор: Олег2005 16.4.2009, 12:42
Цитата(azesmcar @  15.4.2009,  22:35 Найти цитируемый пост)
Засовываю 64 сокета. Вызываю селект. Есть события, обрабатываю, нет событий - засовываю еще 64, пока не кончатся. Таймаут на селект ставлю 0. 

В лоб - но работать будет smile 
Про IO completion port я уже где-то выкладывал - лень искать, выложу еще раз:

Автор: azesmcar 16.4.2009, 13:21
Цитата

В лоб - но работать будет smile 

Работать то будет..но хотелось бы чтобы работало хорошо smile что плохого в этом решении?
Цитата

Про IO completion port я уже где-то выкладывал - лень искать, выложу еще раз: 

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

Автор: azesmcar 16.4.2009, 13:51
Еще одна мысль.
Поскольку сокеты все неблокирующие (так как в этом потоке мне нужно проверять и другие события, не только на сокетах), можно убрать селект вообще. Подробнее...
На данный момент (если забыть про проблему селекта) у меня работает такая схема при каждой проверке события

Код

итерация по всем сокетам
   добавление их в fd_set
запуск селекта
итерация по всем сокетам
   проверка - остался ли сокет в fd_set (т.е. есть ли событие)
      выдать событие обработчику


в случае если убрать селект и проверять события функцией recv на каждом сокете по отдельности, одной итерацией по сокетам будет меньше..что вы об этом думаете?


Автор: vinick 16.4.2009, 15:11
Цитата(azesmcar @  16.4.2009,  13:51 Найти цитируемый пост)
в случае если убрать селект и проверять события функцией recv на каждом сокете по отдельности, одной итерацией по сокетам будет меньше..что вы об этом думаете?


recv как ни крути - системный вызов. Пробежаться по массиву и проверить событие в fd_set в юзерспейсе при большом количестве дескрипторов,  будет дешевле чем впустую дергать recv для каждого сокета. Тут лучше будет экономить не на итерациях по сокетам, а на системных вызовах.

Автор: azesmcar 16.4.2009, 15:16
vinick

Цитата

recv как ни крути - системный вызов. Пробежаться по массиву и проверить событие в fd_set в юзерспейсе при большом количестве дескрипторов,  будет дешевле чем впустую дергать recv для каждого сокета. Тут лучше будет экономить не на итерациях по сокетам, а на системных вызовах.

а точно что будет медленее? подумать не стоит?

Автор: Олег2005 16.4.2009, 15:24
Цитата(vinick @  16.4.2009,  14:11 Найти цитируемый пост)
recv как ни крути - системный вызов. Пробежаться по массиву и проверить событие в fd_set в юзерспейсе при большом количестве дескрипторов,  будет дешевле чем впустую дергать recv для каждого сокета. Тут лучше будет экономить не на итерациях по сокетам, а на системных вызовах. 

Согласен.

Автор: azesmcar 16.4.2009, 15:44
 smile  smile  smile 

ладно...буду думать.

всем спасибо, решенным пока не отмечаю, мало ли..

Автор: vinick 16.4.2009, 16:11
Цитата(azesmcar @  16.4.2009,  15:44 Найти цитируемый пост)
ладно...буду думать.


azesmcar,  как я понял ты используешь С++, тогда я порекомендую использовать готовую библиотеку  http://en.wikipedia.org/wiki/Asio_C%2B%2B_library

Она проста в использовании, кроссплатформенна, подерживает не только windows и Linux но и Solaris, MacOSX и т.п., состоит только из *.h фалов, Она включена в состав буста, но может быть использована и отдельно. 
В крайнем случае ты можешь посмотреть на ее внутрености и попробовать реализовать свое по образу и подобию, выкинув лишнее, там правда очень много шаблонной магии.
Короче то что надо  smile 

Автор: azesmcar 16.4.2009, 16:26
vinick
С++ конечно smile раздел форума С++/Сети называется smile 

У меня своя кроссплатформенная библиотека, с обработкой событий (делегаты, итд, итп...) потому пишу свой класс, чтобы встраивался под общую архитектуру и выдавал события в нужном мне виде...у меня болезненный принцип не использовать ничего написанного сторонними производителями (после работы в одной компании остался осадок smile у них принцип такой был, там научился все писать ручками..). Но посмотреть и написать по образу и подобию - вполне приемлемо smile
Завтра скачаю посмотрю - отпишусь..сегодня уже не успеть..

Спасибо

Автор: MAKCim 16.4.2009, 16:30
Цитата(azesmcar @  16.4.2009,  11:37 Найти цитируемый пост)
Вы видимо темой ошиблись smile это надо было постить сюда


Цитата(azesmcar @  15.4.2009,  22:28 Найти цитируемый пост)
В никсах есть poll как сказал MAKCim, но...как сказали вы - увы

Цитата(MAKCim @  16.4.2009,  11:35 Найти цитируемый пост)
в linux, ребята, есть epoll, а это реально мощная штука


ошибся темой?  smile 

Автор: azesmcar 16.4.2009, 16:39
MAKCim
 smile я уже и забыл про это сообщение

Цитата

в linux, ребята, есть epoll, а это реально мощная штука

Под линукс можно много чего красивого сделать..но нужно кроссплатформенно. 

Автор: J0ker 16.4.2009, 20:22
boost.Asio - pools, queues, IO completion ports

Автор: Олег2005 16.4.2009, 21:44
Цитата(J0ker @  16.4.2009,  19:22 Найти цитируемый пост)
boost.Asio

Кстати, а есть какое руководство - с доходчивым описанием?

Автор: J0ker 16.4.2009, 23:48
Цитата(Олег2005 @ 16.4.2009,  21:44)
Цитата(J0ker @  16.4.2009,  19:22 Найти цитируемый пост)
boost.Asio

Кстати, а есть какое руководство - с доходчивым описанием?

внимательно почитайте Overview - Core Concepts and Functionality и ознакомьтесь с паттерном "реактор"



Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)