Название: Опрос большого числа абонентов по TCP Отправлено: texnik от Октябрь 08, 2010, 12:05 Здравствуйте все.
Проблема следующая. Есть приложение, которое должно периодически опрашивать большое количество абонентов по протоколу TCP, т.е высылать им некие запросы и получать на них ответы. Для каждого абонента набор запросов различный. Сейчас я делаю это так. Формируется пул потоков, каждый из которых обрабатывает одно соединение с абонентом и работу с ним. Сами пакеты формируются отдельно и передаются для отсылки через очередь запросов, полученные пакеты закладываются в очередь ответов и обрабатываются тоже отдельно. Поток вида tcpclientyhread.h Код: #include <QHostAddress> Код: #include "tcpclientthread.h" Возникает проблема, когда открывается множество соединений TCP, имеющих состояние TIME_WAIT (netstat), для закрытия которых требуется значительное в рамках интенсивности опроса время. А затем весь опрос "умирает". Полный цикл опроса всех абонентов должен производится хотя в рамках 10 секунд. Создавать отдельное соединение на каждый абонент не могу из-за количества абонентов, превышающего лимит по соединениям. Нужен ваш совет. Заранее спасибо. Название: Re: Опрос большого числа абонентов по TCP Отправлено: vunder от Октябрь 08, 2010, 13:29 Думаю, все-таки нужно создавать несколько соединений, но не все количество абонентов, а пачками, скажем по 10 штук. Это обычная практика. Сканеры портов, например, именно так и делают: задается максимальное количество потоков, если в очереди есть необработанные клиенты, то проверяется, можно ли создать для него новый поток. Если можно, то поток создается. При завершении работа одного из потока снова проверяется, если ли в очереди клиенты.
Название: Re: Опрос большого числа абонентов по TCP Отправлено: texnik от Октябрь 08, 2010, 14:09 Дело в том, что опросить за период нужно все абоненты, и этот период меньше чем период ожидания для удаления соединения операционной системой.
А если я установлю допустим 10 постоянных соединений, то это будет только 10 абонентов. Название: Re: Опрос большого числа абонентов по TCP Отправлено: vunder от Октябрь 08, 2010, 19:53 Смысл в том, что после обслуживания очередного абонента можно перейти к опросу очередного. Так мы получем несколько потоков для опроса большого числа клиентов
Название: Re: Опрос большого числа абонентов по TCP Отправлено: texnik от Октябрь 09, 2010, 12:16 Смысл в том, что после обслуживания очередного абонента можно перейти к опросу очередного. Так мы получем несколько потоков для опроса большого числа клиентов Ну вообще то я так и делаю. Проблема не в создании множества потоков (пул потоков ограничен), а в том, что после того как производится disconnectFromHost текущее TCP соединение висит в состоянии TIME_WAIT еще более минуты и через некоторое время таких соединений становится слишком много.Название: Re: Опрос большого числа абонентов по TCP Отправлено: SABROG от Октябрь 09, 2010, 21:18 Проблема не в создании множества потоков (пул потоков ограничен), а в том, что после того как производится disconnectFromHost текущее TCP соединение висит в состоянии TIME_WAIT еще более минуты и через некоторое время таких соединений становится слишком много. Насколько я знаю это стандартное поведение протокола TCP/IP и относится ко всем программам, после закрытия сокета он остается открытым какое-то время для операционной системы, чтобы гарантировать доставку пакетов с информацией о завершении соединения. Qt тут не при чем.Название: Re: Опрос большого числа абонентов по TCP Отправлено: texnik от Октябрь 10, 2010, 01:55 Может подскажете в какую сторону "курить"?)
Название: Re: Опрос большого числа абонентов по TCP Отправлено: SABROG от Октябрь 10, 2010, 10:22 превышающего лимит по соединениям А как это выглядит? Вы опросили 1000 абонентов, закрыли все соединения и пытаетесь заново их опросить, а ОС не дает, так как закрытые сокеты остались открытыми где-то внутри ОС и висят с флагом TIME_WAIT?Создавать отдельное соединение на каждый абонент не могу из-за количества абонентов, превышающего лимит по соединениям. Тут я не понял. А как можно не создавать отдельное соединение/сокет на каждого клиента? Broadcasting, который дальше шлюза не уйдет?Название: Re: Опрос большого числа абонентов по TCP Отправлено: texnik от Октябрь 10, 2010, 19:56 А как это выглядит? Вы опросили 1000 абонентов, закрыли все соединения и пытаетесь заново их опросить, а ОС не дает, так как закрытые сокеты остались открытыми где-то внутри ОС и висят с флагом TIME_WAIT? Именно так и выглядит, при опросе для каждого нового абонента создается соединение, производится обмен, потом соединение закрывается. После закрытия соединения сокеты висят с флагом TIME_WAIT некоторое время.Цитировать Тут я не понял. А как можно не создавать отдельное соединение/сокет на каждого клиента? Broadcasting, который дальше шлюза не уйдет? Здесь вероятно я не правильно выразился - я имел в виду то, что возможное количество абонентов значительно больше количества сокетов в ОС и нельзя создать постоянное соединения для каждого абонента. Получается что надо работать с абонентами последовательно, высвобождая сокеты.Название: Re: Опрос большого числа абонентов по TCP Отправлено: SABROG от Октябрь 10, 2010, 22:00 Получается что надо работать с абонентами последовательно, высвобождая сокеты. Это понятно. Непонятно в чем проблема. Просто хочется, чтобы не висели в netstat или всё-таки ОС не дает после определенного количества попыток снова соединяться и программа перестает корректно работать?Название: Re: Опрос большого числа абонентов по TCP Отправлено: texnik от Октябрь 11, 2010, 11:52 Получается что ОС не дает соединяться снова - соответственно и программа перестает корректно работать. Больше не происходит подключения.
Название: Re: Опрос большого числа абонентов по TCP Отправлено: SABROG от Октябрь 11, 2010, 12:23 Получается что ОС не дает соединяться снова - соответственно и программа перестает корректно работать. Больше не происходит подключения. Это известная (http://technet.microsoft.com/ru-ru/magazine/2007.12.network.aspx) проблема p2p клиентов. Для устранения патчат файлик tcpip.sys, чтобы уменьшить время освобождения сокетов протоколом. Другой вариант поставить минимальную задержку перед следующим сканированием одного и того же IP адреса в 300 секунд. Название: Re: Опрос большого числа абонентов по TCP Отправлено: texnik от Октябрь 11, 2010, 13:12 Все ясно. Большое спасибо.
|