Пример Async Sockets, который показывает передачу объекта? - PullRequest
1 голос
/ 06 февраля 2011

Мне нужно создать серверный процесс, который может передавать высокочастотные данные (1000 обновлений в секунду) примерно 50 клиентам.Я думаю, что лучший способ сделать это - использовать асинхронные сокеты с типом SocketAsyncEventArgs.

Соединения клиент -> сервер будут работать долго, по крайней мере, несколько дней до неопределенности.Я планирую прослушивать процесс сервера, и клиенты подключаются, и сервер начинает передавать данные клиентам.

Может кто-нибудь указать мне или показать пример того, как это сделать?Я не могу найти ни одного примера, показывающего процесс сервера, передающий объект клиенту.

EDIT : Это по гигабитной локальной сети.Использование сервера Windows с 16 ядрами и оперативной памятью 24 ГБ

спасибо

Ответы [ 3 ]

1 голос
/ 06 февраля 2011

Во-первых, требуется еще несколько требований с вашей стороны.У вас есть сервер с большим количеством мускулов, но он с треском провалится, если вы не сделаете то, что должно быть сделано.

  1. может ли клиент жить без некоторых данных?Я имею в виду, должен ли поток данных достигать другой стороны в правильном порядке, без каких-либо падений?

  2. насколько велики «данные»?несколько байтов или?

  3. факт: интервал планирования для окон равен 10 мсек.

  4. факт: независимо от того, КОГДА вы отправляете, клиенты получат егов зависимости от множества вещей - конфигурации сети, количества промежуточных маршрутизаторов, загрузки клиентского процессора и так далее.поэтому здесь вам нужна временная метка

В зависимости от всего этого вы можете создать очередь с приоритетом, обслуживая ее одним потоком и отправляя дейтаграммы UDP для каждого клиента.Кроме того, поскольку (4) действует, вы можете «собрать» некоторые свои данные вместе и получить 10 обновлений в секунду из 100 данных.

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

0 голосов
/ 06 февраля 2011

Если вы хотите использовать .NET Sockets для создания этого проекта сервер-клиент, тогда это хорошее описание того, что необходимо:

Поскольку сервер будет передавать данные нескольким клиентам одновременно, вы будетенеобходимо использовать асинхронные методы Socket.Beginxxx или класс SocketAsyncEventArgs.

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

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

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

Вам не нужно беспокоиться о буферизации отправляемых данных, так как TCPстек заботится об этом.Если вы вообще не хотите буферизовать ваши данные (т. Е. Сделать так, чтобы сокет отправлял данные немедленно), установите для Socket.NoDelay значение true.

Не похоже, что вам нужны какие-либоданные от ваших клиентов, но если вы это сделаете, вы должны убедиться, что ваш сервер имеет цикл Socket.BeginReceive при использовании шаблона Socket.BeginXXX или Socket.ReceiveAsync при использовании SocketAsyncEventArgs.

После того, как выЕсли между сервером и клиентом происходит соединение и передача данных, вам нужно беспокоиться о сериализации и десериализации объектов между клиентом и сервером.

Сериализация, которая происходит на сервере, проста, поскольку вы можете использовать BinaryFormatter или другие кодировщики для кодирования вашего объекта и вывода данных в сокет.

Десериализация наС другой стороны, что происходит на клиенте, может быть довольно сложным, потому что объект может охватывать несколько пакетов, и вы можете иметь несколько объектов в одном пакете.По сути, вам нужен способ определить начало и конец объекта в потоке, чтобы вы могли извлечь данные объекта и десериализовать его.

Один из способов сделать это - вставить ваши данные в скважину.известный протокол, такой как HTTP, и отправьте его в этом формате.К сожалению, это также означает, что вам придется написать парсер HTTP на клиенте.Задача не из легких.

Другой способ - использовать существующую схему кодирования, такую ​​как буферы протокола Google .Этот подход потребует обучения использованию стека буферов протокола.

Вы также можете встроить данные в структуру XML, а затем на стороне клиента будет иметься декодер stream-to-XML.Это, вероятно, самый простой подход, но наименее эффективный.

Как видите, это не простой проект, но вы можете начать с примерами Socket.BeginSend здесь и здесь и пример SocketAsyncEventArgs здесь

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

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

Можно использовать TCPClient класс для клиентской реализации, так как он в основном читает поток из сетевого соединения.

0 голосов
/ 06 февраля 2011

А как насчет рандеву или 29 запада? Это спасло бы переизобретение колеса. Не знаю про amqp или zeromq, они тоже могут нормально работать ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...