LINUX.ORG.RU

С/С++, Сокеты, определить и закрыть простаивающие соединения


0

0

Приветствую :)

Подскажите, как средствами системы определить простаивающие соединения (не зависшие клиенты - тут keepalive справляется), а именно простаивающие - клиент на keepalive пакеты отвечает, но полезного обмена данными между клиентом и сервером нет

спасибо.

Ответ на: комментарий от vasily_pupkin

> Все зависит от твоих критериев «полезности» обмена.

Уточняю :) Есть TCP сервер (свой протокол, поверх TCP). Обработка соединений посредством epoll. Клиенты могут быть с «живыми» или «зависшими» соединениями. Зависшие отбрасываются посредством механизма keepalive.

Клиенты с «живыми» коннектами могут ничего не присылать серверу (будут бегать только keepalive пакеты нулевой длины), но никаких полезных данных не приходит (соответсвенно, данный сокет не возвращается из epoll_wait()).

Нужно получить список таких сокетов и закрыть их (чтоб не занимали буфера, да и ограничение дескрипторов на процесс)

А так - man pcap

Не использовал на практике, не знаю насколько это дополнительно нагрузит сетевую подсистему )) Может проще в отдельном потоке периодически проверять время активности сокетов )

GwinnBleidd
() автор топика
Ответ на: комментарий от GwinnBleidd

>Нужно получить список таких сокетов и закрыть их (чтоб не занимали буфера, да и ограничение дескрипторов на процесс)

Идея сделать это программными средствами на ум что, не приходила?

1. Держим список всех открытых соединений. При появлении активности на каком-либо из дескрипторов, устанавливаем в нем время последней активности.

2. Раз, скажем, в минуту проверяем, на каких сокетах давно не было активности и закрываем их, удаляя из списков открытых соединений.

3. pcap — это перехват пакетов, для данной задачи не подходит абсолютно.

linuxfan
()
Ответ на: комментарий от GwinnBleidd

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

vasily_pupkin ★★★★★
()
Ответ на: комментарий от linuxfan

2vasily_pupkin:

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


2linuxfan:

Идея сделать это программными средствами на ум что, не приходила?


это она и была:

Может проще в отдельном потоке периодически проверять время активности сокетов )


Вероятно, вы не совсем внимательно читали первый пост :))

как средствами системы определить простаивающие соединения


Типа как для keepalive установливаются параметры (глобально или для конкретного сокета с помощью setsockopt):
net.ipv4.tcp_keepalive_time = xx
net.ipv4.tcp_keepalive_probes = yy
net.ipv4.tcp_keepalive_intvl = zz

Так и для простаивающих коннектов, и не писать дополнительный код, не заморачиваться над списком активных сокетов

GwinnBleidd
() автор топика

можно смотреть кол-во переданных данных. Попадает ли туда keepalive хз. Как вывести каунтеры тоже не нашёл. Можно по размеру окна судить об активности. Посмотри всякие getsockopt итп.

true_admin ★★★★★
()

Что значит простаивающий? Если клиент не закрыл соединение и не послал сигнал серверу, то зачем его закрывать - это будет нештатное завершение программы.

golodranez ★★★★
()
Ответ на: комментарий от GwinnBleidd

>Клиенты с «живыми» коннектами могут ничего не присылать серверу (будут бегать только keepalive пакеты нулевой длины), но никаких полезных данных не приходит

Может тебе надо прочесать код клиента на предмет «какого фига мы висим на сокете?!» и дописать правило по которому он закрывает соединение.

golodranez ★★★★
()
Ответ на: комментарий от golodranez

>Может тебе надо прочесать код клиента на предмет «какого фига мы висим на сокете?!» и дописать правило по которому он закрывает соединение.

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

linuxfan
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.