| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Сети > Селект возвращеает сокет когда ничего не пришло |
| Автор: Enelar 11.8.2010, 18:04 | ||
У меня в цикле крутится такой код
Дак вот все работает замечательно, потом бац, селект возвращает 1 а новое соединение не пришло. Ну прога естественно виснет на аксепте. P.S Connect это сокет который успешно bind и listen прошел. SetDebugStr это моя функция которая в отличие от принтефа не юзает кеши (напрямую mysql команду). Приложение однопоточно. |
| Автор: Олег2005 11.8.2010, 22:36 |
| Какая ОС? Ну и может это вот поможет: "Существует еще одна особенность применения функции select(). Эта функция – "одноразовая". В чем смысл такой "одноразовости"? Приведем такой пример – функцию по некоторым соображениям выполняют в цикле. И как только она сработала по какому-то состоянию готовности, мы обрабатываем некоторую информацию и снова возвращаемся на select(), что бы вновь отслеживать события. К удивлению нашему, функция не сможет обнаружить ни одного события на сокетах. Почему? Система после срабатывания select() обнуляет маску для данного сокета. И для правильной работы в цикле придется выполнить все необходимые макрокоманды, размещающие признаки ожидания во всех наборах сокетов." |
| Автор: Enelar 12.8.2010, 08:49 | ||
| ОС Ubuntu 10.04 LTS Замечу также что ранее этой ошибки не замечал. И до сих пор не замечаю(если дебажить с ноута или с локалхоста). Но дебажит человек из соседнего района и сервер виснет. P.S виснет при приходе похожих пакетов обозначающих одно действие но с разными параметрами. Возможна запись мимо памяти, но вроде все проверил... Встает вопрос, что за макро команды такие? у меня код следующий
|
| Автор: ilyagoo 12.8.2010, 10:06 | ||||
макрокоманды в данном случае:
перед каждым вызовом select все три fd_set (в вашем случае только один - на чтение) нужно инициализировать заново.
и проверять установлен ли бит FD_ISSET сокета после select. например, рассмотрим ваш код: 1) fd вы не обнулили, а что там находилось? допустим, были ненулевыми какие-то из первых трех битов - это stdin, stdout, stderr (не помню последовательнось). скажем stdin вдруг стал готов на чтение - select вернул как минимум 1. 2) вы попали в тело цикла и не проверяя, установлен ли ваш Connect после select`а счастливо, виснете в accept, т.к. в этот момент был готов на чтение совершенно другой дескриптор)) все. |
| Автор: Enelar 12.8.2010, 10:14 |
| хм. 1) сделаем на всякий случай, но если не ошибаюсь fd_set по умолчанию пустой? 2) если первое не верно, то замечание логично. в противном случае лишняя инструкция. Добавлено через 2 минуты и 6 секунд За решение спасибо, наверняка оно верное... Просто у меня время не ждет, пришлось быстро искать решения. Сделал сокет неблокирующим. А то смысл селект ради одного сокета дергать. |
| Автор: ilyagoo 12.8.2010, 10:28 |
| если я не ошибаюсь, неглобальные переменные не инициализируются сами по себе. если сокет был блокирующим, то можно было поместить его в нить. |