Гость Опубликовано 11 августа, 2001 Жалоба Поделиться Опубликовано 11 августа, 2001 Народ, кто-нибудь работал с unix domain socket? Создаю локальный сокет (AF_LOCAL,SOCK_STREAM,0), делаю bind, listen. Вижу созданый файл сокета, и netstat тоже его показывает и говорит, что он STREAM и LISTENING. Далее добавляю его в FD_SET, делаю select(...). По срабатыванию select() на чтение, проверяю наличие этого сокета, делаю accept... и тут он мне выдает ошибку 11 (EWOULDBLOCK, она же EAGAIN, она же "Resource temporarily unavailable"). Клиентская прога говорит, что сконектилась, а сервер непрерывно сыпет эту ошибку... В чем я ошибся? С inet сокетами тоже самое проходит без проблем. Я уже думал, что локальные сокеты нельзя делать типа STREAM, но bind и listen проходят без ошибок, да и другие программы их применяют (напр. gpm). Доки об этом умалчивают (man socket и info libc). Делал сокет как nonblocking, так и без этого. Кто знает, помогите, пожалуйста. Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 13 августа, 2001 Жалоба Поделиться Опубликовано 13 августа, 2001 не помешал бы кусочек кода... 0. Конечно можно делать STREAM 1. именно accept() возвращает EWOULDBLOCK? 2. Что значит "непрерывно сыпет ошибку"? на каждый коннект? или действительно "непрерывно"? в каком цикле? кода кусочек дай.. 3. EWOULDBLOCK может вернуться только для неблокируещего сокета... в случае без NBLOCK программа должна аблокироваться в accept()... 4. последовательность fd = listen(); select(fd...); if (fd is readable) fd1= accept(fd...) НЕ ГАРАНТИРУЕТ, вообще говоря, что ты не заблокируешься в accept() (так как клиет мог закрыть сединение между select() и accept() и разные unix-ы в этом случае ведут себя по-разному)... поэтому если используешь select() для того чтобы узнать, что соединение готово для accept(), то всегда надо делать неблокирующий listen сокет... это к слову.... не видя кода, можно только предположить, что клиент "умирает" сразу после connect, т.е. пока сервер находится между select() и accept()... =ipv4 Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 14 августа, 2001 Жалоба Поделиться Опубликовано 14 августа, 2001 Благодарю за участие, но с проблемой я разобрался: как всегда - невнимательность - при копировании схожих блоков программы остлось не исправленное имя переменной... ж) http://linux.ru.net/index.php?module=forums&faction=show&message=31007 Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 14 августа, 2001 Жалоба Поделиться Опубликовано 14 августа, 2001 Добавлю к выше сказаному: такой эффект (клиент коннектится и думает что все в порядке, а сервер на каждый accept() выдает ошибку в цикле while(select(.)) и тратит много процессорного времени) получается если в accept() передавать не существующий или не активный не блокируемый сокет. Даже если клиет закроет соединение, то select() продолжает генерить событие чтения для listen сокета (в Linux) и таких событий у меня было по 5-20 тыс. в секунду... Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 14 августа, 2001 Жалоба Поделиться Опубликовано 14 августа, 2001 > Добавлю к выше сказаному: > такой эффект (клиент коннектится и думает что все в порядке, > а сервер на каждый accept() выдает ошибку в цикле > while(select(.)) и тратит много процессорного времени) > получается если в accept() передавать не существующий или не > активный не блокируемый сокет. что == не вызывать accept вообще, не так ли? >Даже если клиет закроет > соединение, то select() продолжает генерить событие чтения > для listen сокета (в Linux) в любом unix. select() немедленно возвращается если есть ready сокеты, а они есть раз ты не вызывал accept(). тут нет никакой ошибки в линуксе, или "эффекта", ни даже чего-то недокументированного, либо "недоописанного" либо специфичного для линукса, как нет и в том, что клиент "думает, что все в порядке". все и есть в порядке! сокет становится ready ПОСЛЕ того как соединение tcp установлено (т.е. ПОСЛЕ syn, syn_ack, ack). accept() ничего не "акцептует" =ipv4 =ipv4 Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 14 августа, 2001 Жалоба Поделиться Опубликовано 14 августа, 2001 ложный вызов... жаль... =ipv4 Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 15 августа, 2001 Жалоба Поделиться Опубликовано 15 августа, 2001 После вызова connect() клиенту сразу возвращается управление (т.е., практически, соединение установлено на уровне TCP, но логически, программа сервер канал еще не создала). А в accept() я по ошибке пердавал номер другого listen сокета, на что получал -1. Подобной ошибки не ожидал и вся обработка сводилась к выводу сообщения об ошибке, а потом к началу цикла, к select(). А там по новой... В целом, забавно получилось ж) Судя по всему, в libc (или glibc) делается буферизация событий, и даже когда клиент зактыл свой сокет, на серверной стороне остались события конекта (на listen сокете) и EOF (на еще не подтвержденном, не существующем сокете)... Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 17 августа, 2001 Жалоба Поделиться Опубликовано 17 августа, 2001 нет никакой "буфферезации собыий"... нету ее... пока ты не сделаешь accept, raedable listem socket остается readable вечно... единственный способ его сделать не readable это "прочитать", т.е. accept-овать... состояние клиента не имеет отношения к его readbility... в линуксе... в BSD если клиент сделает close() до того как ты сделаешь accept() (как в твоем случае из-за ошибки и происходит), то socket перестанет быть readable, если на нем без accept еще раз в select уснуть... но это приводит к тому, что есть шанс уснуть в accept() даже после select!... и это значит что надо использовать O_NBLOCK итд итп... в линукс (как и в SVR4) сокет остается readble пока его не accept-уешь, и accept() вернет ошибку, если между select и accept клиент успел сделать close() =ipv4 Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.