![]() |
|
Модераторы: xvr |
![]()
|
|
| konshyn |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
Открываю 1000-2000 udp сокетов
Использую опцию SO_REUSEADDR. Потом делаю bind() на такой адрес:
после рестарта программы, при bind() ошибки не выдает, но на эти сокеты в течение 5-10 минут (примерно) ничего не приходит. как с этим справиться? -------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
|||
|
||||
| feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 1 Всего: 45 |
А какой здесь смысл в SO_REUSEADDR для udp-сокетов?
Поясните, пожалуйста, идут ли вообще на эти порты данные в течении этих 5-10 минут, и как Вы работаете с таким немалым набором сокетов. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
| konshyn |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
Работаю с помощью epoll. Я не знаю, идут ли данные, но счетчик показывает, что не идут. Я до этого открывал 1024 сокета, но netstat не показывал около 300 открытых портов, потом я уменьшил до 512 кол-во сокетов. netstat показывал все.
Когда уменьшил кол-во сокетов, проблем стало меньше при рестарте. Потом оставил всего один сокет, и проблемы ушли. Напрашивается вывод, что кол-во сокетов влияет на мою проблему, а может и нет. Суть задачи в том, что данные должны отправляться на >1000 различных портов, а на другой стороне принимаются. Как можно решить эту задачу с помощью ресурсов ОС Linux? -------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
|||
|
||||
| feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 1 Всего: 45 |
Как вызван epoll_create?
Не понял. Через sendto и recvfrom можно работать с одним udp-сокетом. SO_REUSEADDR здесь не нужен. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
| konshyn |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
Переменная send_socket нужна для отправки данных на различные порты, т.к. если я в функцию бросаю сокет, к которому применил bind, он говорит, что INVALID ARGUMENT, скорее всего потому что bind() был на INADDR_ANY. -------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
|||
|
||||
| feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 1 Всего: 45 |
Честно говоря, довольно трудно судить о том, что у Вас происходит в программе. Ну, например:
Код инициализации массива listevents приведен, а массива events - нет, посему так и остаешься в приятном недоумении, используете ли Вы далее неинициализированный массив events (кстати, зачем Вам два массива?). В операторе
я бы червячка убрал, не нужен он. Так же ещё раз хочу обратить Ваше внимание на то, что опция SO_REUSEADDR не нужна при рестарте udp-сокетов. Для сокета send_socket я бы еще задал событие EPOLLOUT и его обработку (на случай, если внутренний буфер сокета на передачу вдруг переполнился). В какую функцию? sendto? Маловероятно, т.к. bind в данном случае лишь принудительно задает номер исходящего порта. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
| konshyn |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
Не знаю, как он туда попал. В коде его нет:)
использую. просмотрите цикл while, в котором используется epoll_wait().
send_socket инициализирован специально, потому что если я использую сокеты, которые за'bind'ил и которые потом включил в список epoll, для отправки сообщений через sendto, то выдает ошибку invalid argument. send_socket не надо включать в список, и если буфер отправки будет переполнен, то мне надо ждать, чтобы отправить следующий пакет. send_socket - блокирующий сокет.
это я понял, потому что с одним сокетом проблем нет. а когда их 500 - есть. -------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
||||||
|
|||||||
| feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 1 Всего: 45 |
Понял. А Вы все это (epoll_wait и sendto) в одном потоке делаете?
Ну вот участие сокета в epoll - более вероятная причина такого поведения, хотя с этим было бы неплохо разобраться до конца... Что именно? Зачем нужна или не нужна опция SO_REUSEADDR при рестарте tcp-сервера или udp-сервера? Вот тут надо бы плотно заняться тем, что у Вас происходит в самом сервере (я сильно намекаю на выдачу отладочных сообщений в какой-нибудь уникальный лог-файл). -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
| konshyn |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
да, т.к. передача данных между потоками или использование атомарности мне кажется более ресурсоемкой задачей. хотя для 3 потоков в своей программе не проверял, но при 100 сокетах и потока на каждый сокет данные передавались с огромной задержкой. в кажом потоке был блокирующий сокет. получается, при вызове recvfrom(), если пакет не приходил именно на тот порт, то поток "засыпал", и когда приходил пакет на нужный порт - то нужный поток ядро должно было "будить" и передавать данные в буфер. но на практике это оказалось как-то совсем нерабочей версией. хотя написанный код в моем случае уменьшался в 2 раза. epoll был лучшим решением и оно работает, но есть проблема - она в этой теме:)
интересная мысль, спасибо за наводку. попробую и потом напишу.
что для UDP сокетов не нужен SO_REUSEADDR. Добавлено через 14 минут и 2 секунды
Хотя подумал - мало вероятно, т.к. когда делаю 1-2 сокета с epoll'ом все работает. Но покопать все-таки в эту сторону стоит. -------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
||||||
|
|||||||
| feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 1 Всего: 45 |
Так я ни слова не сказал против epoll, наоборот, я двумя руками за. Что мне кажется крайне сомнительным, так это существование двух блокирующих вызовов в одном потоке. Кстати, а данные, которые Вы посылаете через sendto( send_socket, ...), неужели они предназначены той тысяче сокетов, которые в epoll_wait? Я, честно говоря, так и не понял сути проблемы. Вы пишете:
У меня, к сожалению, нет под рукой линукса, чтобы проверить, но странно как-то это. Такое впечатление, что сокеты медленно открываются или привязываются к портам. Я еще раз настойчиво советую Вам выдачу отладочных сообщений (с как минимум посекундным текущим временем), например:
И так далее, и тому подобное. Времени это займет не много, а вот понимания происходящего в программе добавит. Это сообщение отредактировал(а) feodorv - 5.10.2014, 04:36 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
| konshyn |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
Их там больше, но максимальная последовательность - 3 блокирующих вызова. epoll_wait(), recvfrom(), sendto(). А почему это сомнительно? Пакет приходит на карточку, процесс выходит из epoll_wait(), ядро копирует с карточки в буфер процесса, пакет обрабатывается и если надо, отправляется. Насколько я понимаю, пакеты приходят по одному, а не несколько штук параллельно, и нет смысла ядру копировать в буфер процесса пакет, который пришел позже. А т.к. мне все нужно делать попорядку, то последовательные действия с ожиданием их завершения мне показалось лучшим решением. разве что на отправку можно снять блокировку, но пока что нагрузка небольшая, поэтому проблем не возникало с блокировкой. Напишите, пожалуйста, свое мнение на этот счет. Может я что-то упустил.
Да.
Сделаю. Как будет готово, напишу. Это сообщение отредактировал(а) konshyn - 5.10.2014, 15:48 -------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
||||||
|
|||||||
![]()
|
| Правила форума "С/С++: Программирование под Unix/Linux" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |