Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> закрыть сокеты по таймауту, мониторинг открытых сокетов 
:(
    Опции темы
slater
Дата 3.6.2011, 08:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 168
Регистрация: 20.11.2009

Репутация: -2
Всего: -4



день добрый!

блок схема  программы вобщем то такая:

main процесс ждет соединения, и на каждое новое соединение делает fork().

данные о подключившихся я храню в глобальной структуре( дескрипторы подключившихся сокетов). Так же храню время последнего сеанса приема или отправки данных для каждого сокета.

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


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

товарищи, подскажите пожалуйста более разумное решение.

p.s. по событиям(poll(), epoll()) такая задача не решается, как я понял после гугления ввиду того, что события не придут если овалиться сеть и т.д. поэтому хотелось бы надежное решение данного вопроса.

заранее спасибо всем

Добавлено через 14 минут и 12 секунд
в идеале я бы хотел для каждого сокета заводить свой таймер, и хендл бы по(по истичению времени) посылал сигнал соответствующему процессу и решал бы сразу две задачи: закрывал сокет, убивал бы этот процесс и освобождал бы связанные с процессом ресурсы.


но, наверное смешно делать на 1000 соединений 1000 таймеров. да и системе будет наверное плохо.

 
PM MAIL   Вверх
afiskon
Дата 3.6.2011, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 31.3.2011
Где: Россия, Москва

Репутация: нет
Всего: 4



Я так понял, у вас классическая схема - один процесс слушает порт, остальные процессы обрабатывают каждый своего клиента, так? Ну так используйте в дочерних процессах асинхронные сокеты и проверяйте в перерывах между получением/отправки данных, сколько времени клиент неактивен. Ну или SIGALRM заюзайте. Его, правда, все время придется "продлевать", но это небольшая проблема.
PM MAIL WWW   Вверх
slater
Дата 3.6.2011, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 168
Регистрация: 20.11.2009

Репутация: -2
Всего: -4



Цитата(afiskon @ 3.6.2011,  11:44)
Я так понял, у вас классическая схема - один процесс слушает порт, остальные процессы обрабатывают каждый своего клиента, так?

совершенно верно

Добавлено через 43 секунды
Цитата(afiskon @ 3.6.2011,  11:44)
Ну так используйте в дочерних процессах асинхронные сокеты и проверяйте в перерывах между получением/отправки данных, сколько времени клиент неактивен.

если  не затруднит, можно на примере показать?
PM MAIL   Вверх
xvr
Дата 3.6.2011, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 20
Всего: 223



Цитата(slater @  3.6.2011,  08:05 Найти цитируемый пост)
p.s. по событиям(poll(), epoll()) такая задача не решается,

как раз решается. У poll и select есть параметр timeout. Так что можно задать, сколько времени можно ждать активности на сокете, при выходе по timeout'у - прибивать сокет

PM MAIL   Вверх
slater
Дата 3.6.2011, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 168
Регистрация: 20.11.2009

Репутация: -2
Всего: -4



Цитата(xvr @ 3.6.2011,  13:05)
Цитата(slater @  3.6.2011,  08:05 Найти цитируемый пост)
p.s. по событиям(poll(), epoll()) такая задача не решается,

как раз решается. У poll и select есть параметр timeout. Так что можно задать, сколько времени можно ждать активности на сокете, при выходе по timeout'у - прибивать сокет

было бы здорово, если через epoll().

только не могу понять как это сделать, подскажите, желательно на примере, например, если последний коннект сокета был более чем пять секунд, то его закрыть автоматически
PM MAIL   Вверх
MAKCim
Дата 4.6.2011, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



пусть таймаут - N сек.
тогда
Код

int timeout = N * 1000;
for (;;)
{
    struct timeval start, end, diff;
    int error;
...
    gettimeofday(&start, NULL);
    error = epoll_wait(epfd, events, maxevents, timeout);
    gettimeofday(&end, NULL);
    /* проверяем error < 0, т. е. ошибка epoll_wait */
    error = handle_events(events, error);
    if (error == [число активных сокетов])
    {
        timeout = N * 1000;
    }
    else
    {
        timersub(&end, &start, &diff);
        timeout -= (diff.tv_sec * 1000 + diff.tv_usec / 1000);
    }
    if (timeout <= 0)
    {
        close_connects();
        timeout = N * 1000;
    }
}

handle_events возвращает число активных сокетов
по сути это error + K, где K - это число новых сокетов (в epoll может быть listen сокет)


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
slater
Дата 5.6.2011, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 168
Регистрация: 20.11.2009

Репутация: -2
Всего: -4



Максим, спасибо!

вот только не совсем понял это:

handle_events возвращает число активных сокетов
по сути это error + K, где K - это число новых сокетов (в epoll может быть listen сокет) 


можно поподробнее объяснить?
PM MAIL   Вверх
slater
Дата 6.6.2011, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 168
Регистрация: 20.11.2009

Репутация: -2
Всего: -4



появились еще пара вопросов, на которые я точно и однозначно ответить не могу:

1) epoll_wait() ждет timeout миллисекунд для каждого файлового дескриптора в списке или же с момента блокировки epoll_wait() ( т.е. с момента вызова функции)???

2) все новые сокеты, которые законектились ко мне на сервер, я перевожу в неблокируемый режим и добавляю их в список epoll_ctl(). Все соединения(чтение и запись) я обрабатываю в одном потоке по событиям ( epoll_wait() ).

правильно ли будет, если я просто буду писать данные в неблокируемый сокет через write()?
потому что не совсем понятно, нужно ли использовать select(), если сокеты уже в неблокируемом режиме и отслеживаются epoll_wait()???
PM MAIL   Вверх
slater
Дата 8.6.2011, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 168
Регистрация: 20.11.2009

Репутация: -2
Всего: -4



вобщем, разобрался.

1) epoll_wait() ждет timeout, начиная с того момента, как происходит вызов epoll_wait()
2)write() и read() для nonblocking socket fd делать по событиям RPOLLIN и EPOLLOUT.
3)лучше варианта, чем предложил Максим, не нашел. Поэтому, для каждого активного сокета делать привязку last_time и после получения события или по timeout перебирать все сокеты и сравнивать время.
вот только один нюанс. в manах написано, что если сокет закрт другой стороной, API epoll удалит socket fd из epfd. у меня же свой список активных соединений.

Как мне связать удаление сокета из epfd(которое происходит автоматически внутри интерфейса epoll) со своим списком соединений?

Это сообщение отредактировал(а) slater - 8.6.2011, 09:32
PM MAIL   Вверх
slater
Дата 13.6.2011, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 168
Регистрация: 20.11.2009

Репутация: -2
Всего: -4



up
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0771 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.