Подход к созданию UDP-сервера?

Я новичок в Java NIO.

У меня есть java-программа, которая итеративно запрашивает серверы (разные IP-адреса/порты) в цикле. Но теперь я хочу отправить все пакеты сразу, а не в цикле, а затем сохранить полученные данные в ответном пакете.

Запрос состоит только из 1 ответного пакета, дальнейшая связь не требуется.

это способ сделать это -> Сделать дейтаграммный канал, отправить все пакеты через .send() , прослушать пакеты и запустить новый поток для обработки и хранения данных пакета.

количество серверов может быть> 400. Что лучше сделать 400 потоков или 400 дейтаграммных каналов??? Также я должен использовать асинхронный пакет вместо NIO.

Было бы проще с Нетти и т. д.?


person Community    schedule 14.06.2012    source источник
comment
Сначала я бы запустил обычный NIO. Стоит отметить, что TCP надежен, а UDP — нет. Вы должны учитывать тот факт, что какой-то пакет может не прийти. Для 400 TCP-соединений я бы все равно использовал один поток, если только не было веской причины поступить иначе.   -  person Peter Lawrey    schedule 14.06.2012
comment
серверы отвечают только на UDP. Потерянные пакеты не проблема.   -  person    schedule 14.06.2012


Ответы (2)


Я недостаточно знаком, чтобы советовать NIO, но что касается обработки ответов - лучше использовать пул потоков и пул каналов.

ИЗМЕНИТЬ — дополнительные пояснения

У вас должен быть только один поток, который прослушивает порт, на который отвечают серверы. Получив ответ, отправьте «задачу обработки» в очередь задач. Следующий доступный поток возьмет эту задачу и обработает ее.

Итак, если у вас больше ответов (= задач), чем доступных потоков, задачи будут ждать в очереди. Java имеет хорошую поддержку пула потоков в java. пакет util.concurrent. Эти пределы, конечно, настраиваются.

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

person yair    schedule 14.06.2012
comment
если я создаю пул потоков с 50 потоками, а полученные ответные пакеты равны 51 . Что будет с дополнительным пакетом? - person ; 14.06.2012
comment
@Solution, почему у вас 50 потоков, когда один поток может получить 51 пакет? - person Peter Lawrey; 14.06.2012
comment
если пакет получен, пока этот поток все еще обрабатывает предыдущий пакет, что произойдет? - person ; 14.06.2012
comment
yair, использование threadpool не так просто, как вы советуете. Трудно представить, зачем обрабатывать все пакеты одновременно — это означает, что между пакетами и порядком их отправки нет никакой связи. Стандартные исполнители в java, вероятно, неправильная идея. Мое эмпирическое правило заключается в обработке синхронно/в потоке всех сообщений/пакетов/и т. д. из одного и того же источника. - person bestsss; 17.06.2012
comment
@bestsss, похоже, отправка заказа не имеет значения. Любая другая логическая связь между ответами может быть обработана в потоке, отличном от потока прослушивания. Итог — обработка ввода-вывода и бизнес-логика должны быть разделены. Обозначенные потоки являются рабочими. Рабочая очередь - это передача между ними. - person yair; 17.06.2012
comment
Я никогда не хотел использовать поток прослушивания для переноса логики, просто используя разные конвейеры/очереди для каждого источника. Наличие абсолютно независимых пакетов UDP встречается довольно редко. Модель потока не имеет ничего общего с бизнес-логикой, однако, если 50 сообщений собираются вместе, и всем им требуется общий ресурс, весь пул потоков застревает. - person bestsss; 17.06.2012
comment
@bestsss, если вы можете позволить себе открыть более 400 портов и создать более 400 прослушивающих потоков - тогда вы правы, кодировать и поддерживать проще. Однако, если вы не можете (что часто бывает, хотя не знаете об этом вопросе) или думаете о масштабируемости - вам нужно объединить свои ресурсы. В этих случаях пул должен быть точно настроен, чтобы выдерживать ожидаемую пропускную способность (что может быть тем, что вы назвали непростым). - person yair; 17.06.2012
comment
даже если у вас 400 портов, вам все равно нужен один (или несколько) потоков, а не 400. Ванильные исполнители в java просто не подходят для этой работы, вы можете иметь пул потоков и конвейерное выполнение примерно в 200-250 строк кода. - person bestsss; 17.06.2012
comment
я запрашиваю игровые серверы, поэтому связь состоит только из 1 пакета, и все серверы независимы друг от друга. Сейчас я пытаюсь создать PacketSenderThread, PacketListenerThread, PacketProceserThread, QueueThread, DatabaseUpdaterThread. Это нормально ? - person ; 18.06.2012
comment
И порядок отправки/получения пакетов не имеет значения. Спасибо. - person ; 18.06.2012
comment
Не должно быть QueueThread, просто структура данных очереди. PacketListenerThread помещает данные ответа в очередь, а PacketProcessorThread удаляет их и обрабатывает. DatabaseUpdaterThread может существовать или нет. Это не зависит от способа получения ответов из сети. Пожалуйста :). - person yair; 19.06.2012

Если вы собираетесь использовать UDP, вы можете использовать один поток на сервер и один порт для всех. Вы можете использовать несколько портов для разных типов сообщений.

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

person Peter Lawrey    schedule 14.06.2012
comment
существует ли какая-либо существующая библиотека/открытый исходный код, который обрабатывает несколько одновременных пакетов в java. Любой образец кода также подойдет. Спасибо. - person ; 14.06.2012
comment
Сколько сетевых адаптеров вы перечисляете? Если у вас соединение 1 ГБ и размер ваших пакетов 1 КБ, расстояние между ними не будет меньше 10 микросекунд. Если вы не отправляете близко к 100 КБ / с, они будут отправляться почти в случайное время. - person Peter Lawrey; 14.06.2012
comment
как долго метод .receive() работает в канале дейтаграмм? Например. если я отправлю пакет с помощью .send() и поставлю точку останова... подождите некоторое время... могу ли я успешно использовать .receive(). Спасибо. - person ; 18.06.2012
comment
Пакеты UDP имеют некоторые очереди в вашем маршрутизаторе и вашей ОС. Когда эти очереди заполняются, пакеты молча отбрасываются. Я предлагаю вам попробовать отладить ваше приложение и посмотреть, что произойдет. ;) - person Peter Lawrey; 18.06.2012