Широковещательная передача, подобная UDP, с надежностью TCP

StackOverflow https://stackoverflow.com/questions/31572

  •  09-06-2019
  •  | 
  •  

Вопрос

Я работаю над .net-решением, которое полностью запускается внутри одной сети.Когда пользователи вносят изменения в систему, я хочу запустить объявление, чтобы все остальные услышали его и действовали соответственно.Есть ли способ, которым мы можем передавать подобные сообщения (например, UDP позволит вам это делать), сохраняя при этом гарантированную доставку (например, TCP)?

Это в небольшой сети (30 тысяч клиентов), если это что-то изменит.

Это было полезно?

Решение

Почти все игры нуждаются в свойствах быстрой реакции (и, в меньшей степени, в свойствах отсутствия установления соединения) UDP и надежности TCP.Что они делают, так это создают свой собственный надежный протокол поверх UDP.Это дает им возможность просто отправлять пакеты куда угодно и, при необходимости, делать их надежными.

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

Ваша ситуация кажется очень простой.Вероятно, вы сможете самостоятельно создать самое чистое решение - просто заставьте каждого клиента отправлять ответ "Я вас услышал" и попросите сервер продолжать попытки, пока он не получит его (или не откажется).

Если вы хотите чего-то большего, большинство пользовательских библиотек протоколов находятся на C ++, поэтому я не уверен, насколько они будут вам полезны.Однако моим знаниям здесь всего несколько лет - возможно, некоторые протоколы уже были перенесены.Хм...RakNet и enet - это две библиотеки C / C ++, которые приходят на ум.

Другие советы

Взгляните на sctp который обладает комбинацией функций tcp и udp.Там есть окна реализация Доступно.

Вы могли бы использовать Распространение заниматься групповым общением.

@epatel - Я поддерживаю предложение SCTP (я проголосовал "За", но пока не могу прокомментировать дополнительные материалы здесь).

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

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

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

Возможно, вы захотите заглянуть в RFC 3208 "Спецификация надежного транспортного протокола PGM".

Вот аннотация:

Pragmatic General Multicast (PGM) является надежным средством многоадресной передачи
протокол для приложений, требующих упорядоченного или неупорядоченного,
многоадресная передача данных без дублирования доставка из нескольких источников в
несколько приемников.PGM гарантирует что приемник в группе либо получает все пакеты данных от transmissions and repairs, либо способен обнаруживать невосстановимые данные потерю пакетов.PGM специально разработан как работоспособное решение для многоадресных приложений с базовыми требованиями к надежности.Его центральной целью проектирования является простота эксплуатации с должным учетом масштабируемости и эффективности сети.

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

Apache ActiveMQ - это брокер сообщений написанный на Java вместе с полноценным JMS-клиентом.Однако Apache ActiveMQ предназначен для обмена данными по ряду протоколов, таких как Stomp и OpenWire, а также поддерживает ряд клиентов, зависящих от различных языков .

Поддержка клиентской платформы включает c # и .net

Вы могли бы реализовать свое собственное поведение, подобное TCP, на прикладном уровне.

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

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

Создайте TCP-сервер.Попросите каждого клиента подключиться.В вашем TCP-протоколе с клиентами создайте каждый пакет с 2-байтовым префиксом общего размера следующего сообщения.

Затем клиенты звонят read(max_size=2) в сокете, чтобы определить размер следующего сообщения, а затем read(max_size=s) чтобы забрать сообщение.

Вы получаете надежные, упорядоченные и простые сообщения.Для этого вам не нужна платформа обмена сообщениями.

Ты бы определенно хотите заглянуть в Прагматичная Общая Многоадресная рассылка:

В то время как TCP использует ACKS для подтверждения отправленных групп пакетов (что-то, что было бы неэкономично использовать многоадресную рассылку), PGM использует концепцию негативных подтверждений (NAK).

Для дальнейшего G-дайвинг, термин, который вы ищете, - это надежная многоадресная рассылка.Также взгляните на Многолучевой TCP.

Что вы можете сделать, так это то, что после трансляции у вас будет клиенты инициируйте tcp-соединения.В противном случае вам просто нужно вести список всех клиентов и самостоятельно инициировать подключения к каждому клиенту.

Я думаю, что, вообще говоря, есть три варианта:

  1. Вместо широковещательной передачи UDP вы могли бы создать объект (поток, процесс, сервер, службу или что-то еще, что существует в вашем решении), который хранит список подписчиков и отправляет им одноадресные UDP-сообщения.
  2. Используйте многоадресную рассылку UDP, но вам придется написать какой-то механизм, который позаботился бы о надежной доставке для вас (т. Е. о повторных попытках, тайм-аутах и т.д.).Это также означает, что вы должны получить ответ от своих клиентов.
  3. Если вы не боитесь экспериментальных транспортных протоколов, вы могли бы посмотреть здесь для предложений.,

Вам следует взглянуть на спецификацию Norm (NACK-ориентированная надежная многоадресная рассылка).Вы можете найти информация о Норме здесь.

Протокол NORM разработан для обеспечения сквозной надежной передачи объектов или потоков массовых данных по общей многоадресной маршрутизации IP и служб переадресации.NORM использует механизм выборочного отрицательного подтверждения (NACK) для передачи надежности и предлагает дополнительные протокольные механизмы для проведения надежных сеансов групповой рассылки с ограниченной "априорной" координацией между отправителями и получателями

Это очень хорошо известно в военном мире.

Нормальные характеристики.

Источник нормы

Зачем создавать что-то с нуля, если вы можете использовать библиотеку?Особенно для такого небольшого проекта?

Попробуйте использовать Ведущий который сам использует надежный многоадресный обмен сообщениями - PGM, написан на .NET и с полным исходным кодом.Вы получите хороший движок паба / саба с легко доступной фильтрацией по темам.Или вы можете узнать из кода, как это сделать, и основать на этом свое собственное расширение.

Я думаю, что наиболее раздражающей особенностью TCP в этих сценариях является способность / способ сортировки входящих пакетов в их первоначальном порядке - концепция потока.Вы не можете прочитать байт до тех пор, пока не появится байт, предшествующий ему.

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

выполните многоадресную рассылку по протоколу RDP.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top