![]() |
Модераторы: xvr |
![]() ![]() ![]() |
|
kometa_75 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 62 Регистрация: 24.10.2007 Репутация: нет Всего: нет |
Пытаюсь разобраться с kqueue, пересмотрел множество примеров и хелпов, но не могу понять один момент, а именно - как правильно удалить событие. Вот код(простой эхо-сервер):
Пока клиенты подключены, всё работает нормально. После отключения клиентов события всё равно продолжают поступать. Такое впечатление, что они не удаляются. Помогите, кто в курсе дела. Это сообщение отредактировал(а) kometa_75 - 14.4.2008, 16:31 |
|||
|
||||
MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
kometa_75,
у вас сокет закрывается кроме того насколько я вижу, идет уменьшение kq_clients_used
т. е при вызове kevent() уменьшается размер передаваемого массива kevent а с учетом того, что элемент массива kq_clients_list не перемещается, а просто помечается как удаленный (EV_DELETE), возникшее событие на сокете, полученном через JoinClient(), не будет получено -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
kometa_75 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 62 Регистрация: 24.10.2007 Репутация: нет Всего: нет |
Спасибо, что ответили ))
1. Да, насчёт сокета вы были правы. 2. Не совсем понятно, что делать с массивом и счётчиком kq_clients_used. Если убрать только закрытие сокета, то сообщения о закрытии будут приходить бесконечно. Пробовал ставить EV_DISABLE | EV_DELETE, всё одно не помогает. Очевидно, что надо что-то делать с массивом kq_change_list, но что ? Вообще в сети встретил два вида примеров: Первый. -событие удаляют как я, только потом иногда(почему-то) сразу вызывают что-то типа такого:
причём в некоторых примерах используют локальный экземпляр struct kevent. Второй. -не используют макрос EV_SET. Всё вручную. -используют какие-то свои реализации массивов с хитрым распределением памяти и т.п. Подобные "обёртки" я не смог осилить. PS. Встретил несколько жалоб на аналогичный моему случай. Ответов, увы, не нашёл. Неужели всё так безнадёжно. На линуксе у меня с epoll проблем никаких не было. Это сообщение отредактировал(а) kometa_75 - 15.4.2008, 11:17 |
|||
|
||||
kometa_75 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 62 Регистрация: 24.10.2007 Репутация: нет Всего: нет |
Путём долгих проб и ошибок, наконец-то заставил работать мой пример. Вот как он теперь выглядит:
"Вдохновлялся" кодом отсюда - http://svn.inspircd.org/index.cgi/trunk/in...d/?pathrev=6557 ЗЫ. Так и не могу объяснить, почему именно так надо делать. Тему не закрываю, вдруг кто-нибудь ответит на вопрос - как всё-таки правильно удалять(теперь уже и работать) с этим загадочным механизмом kqueue(ох и название). Это сообщение отредактировал(а) kometa_75 - 15.4.2008, 16:11 |
|||
|
||||
fray |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 7.6.2007 Репутация: нет Всего: 0 |
я так понял это был сервер с одним клиентом. У меня тоже kqueue и тоже непонятки:
здесь один сокет и как мне кажется он дожен записать в сокет один раз потом прочитать и выйти.
Но на деле получасется так, прога пишет более одного раза потом один раз читает и выходит, Почему не получается сразу читать после первой "записи", то есть не выключатся сокет на запись.
Это сообщение отредактировал(а) fray - 18.4.2008, 19:50 |
||||
|
|||||
kometa_75 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 62 Регистрация: 24.10.2007 Репутация: нет Всего: нет |
На самом деле при записи надо ещё некоторые вещи сделать. Посмотрите на код, ссылку на который я приводил. Ещё можно глянуть здесь - http://forums.ascentemu.com/ (эмулятор сервера ВоВ). У меня такой проблемы нет, поскольку я создаю событие только на чтение, соответственно с записью всё в порядке. Надеюсь, что это правильный подход.
|
|||
|
||||
fray |
|
||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 7.6.2007 Репутация: нет Всего: 0 |
с чекаутив это http://svn.inspircd.org/index.cgi/trunk/in...d/?pathrev=6557 и делая как в socketengine_kqueue.cpp Если я добовляю событие с на запись с флажками EVFILT_WRITE, EV_ADD | EV_ONESHOT (line: 11 моего кода см.выше) то получаю только так типа код
./prog rb: 76 write read Писать начал только один раз, но перестал читать. ![]() Если я удаляю добавление события на чтение, то это никак не влият на результат, вот так...
вот так, что за kqueue-бред что он сам добавляет события на чтение(в poll такого нет) ? ![]() Это сообщение отредактировал(а) fray - 21.4.2008, 10:36 |
||||||||
|
|||||||||
kometa_75 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 62 Регистрация: 24.10.2007 Репутация: нет Всего: нет |
Ваш код отличается, от того который в ссылках. Вы не так используете массив kq_events. Его надо использовать только при опросе сообщений(ну и при обработке, соответственно). Во всех остальных случаях надлежит использовать локальные экземпляры struct kevent.
Я не до конца понимаю, что должен делать ваш код. Смущают некоторые моменты, например вот это
Это сообщение отредактировал(а) kometa_75 - 21.4.2008, 10:35 |
|||
|
||||
fray |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 7.6.2007 Репутация: нет Всего: 0 |
fd[i] = make_connect(); примерно выглядит так int make_connect (void) { int sd = socket(); if (fcntl(sd, F_SETFL, O_NONBLOCK) == -1) perror("fcntl"); connect(sd); return sd; } конечно можно написать так
Добавлено через 5 минут и 37 секунд А можно по подробней, что и не так делаю? Это сообщение отредактировал(а) fray - 21.4.2008, 10:59 |
||||||
|
|||||||
kometa_75 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 62 Регистрация: 24.10.2007 Репутация: нет Всего: нет |
Я так понял, что у вас обычное серверное приложение. Исходя из этого предположения, вот какой я написал код:
Эта модель у меня работает. Если хотите "автоматизировать" ещё и отправку данных, то необходимо ещё создавать событие на запись, и после каждой обработки события определять событие для записи. Я этого не делал, поскольку сам контролирую процесс отправки данных. Это сообщение отредактировал(а) kometa_75 - 21.4.2008, 12:17 |
|||
|
||||
fray |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 7.6.2007 Репутация: нет Всего: 0 |
Не наоборот у меня клиент. И проблема вырисовалась так - почему когда я добавил мониторить событие на запись у меня присутсвует событие и чтение, почему когда я удалил событие на запись оно осталось ? Последний вариант выглядит так.
Я хочу чтобы клиент по очереди читал потом писал и так далее..., но событие не удаляется ( EV_SET(&kq_events[i], kq_events[i].ident, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);) и продолжает писать, пишит несколько раз, а мне хотелось чтобы прога работала написал-прочитал. а у меня по запуску выдает это, то есть получается что флажки на запись и чтение подняты ссамого начала. (rb: - сколько байт мы отправили)
хотя как мне кажется ответ должен быть таким...
Это сообщение отредактировал(а) fray - 21.4.2008, 15:13 |
||||||
|
|||||||
kometa_75 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 62 Регистрация: 24.10.2007 Репутация: нет Всего: нет |
По-моему, в вашем случае должно быть примерно так:
|
|||
|
||||
fray |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 7.6.2007 Репутация: нет Всего: 0 |
||||
|
||||
kometa_75 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 62 Регистрация: 24.10.2007 Репутация: нет Всего: нет |
Меня это тоже интересует, однако так делается в примерах рабочего кода, а подход с двумя массивами у меня тоже не работает. Кстати, с epoll я также работаю через локальные экземпляры struct epoll_event, и ничего, нормально всё. Ну а как ваш код, заработал ? |
|||
|
||||
fray |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 7.6.2007 Репутация: нет Всего: 0 |
Нет не заработал, просто нигде не могу найти пример клиента на основе kqueue, одни серверы, просто пытаюсь сделать как у них(freebsd) описано тут http://people.freebsd.org/~jlemon/papers/kqueue.pdf на странице 6 стравнение с poll, на роll'e уменя все работает, вот тоже самое на kqueue нет ![]() |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С/С++: Программирование под Unix/Linux" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |