Как мне написать небольшой пробел в сетевом потоке? - PullRequest
0 голосов
/ 27 мая 2018

У меня есть сервер, который отправляет данные телеметрии различного размера получателям или, как я их назову, клиентам, через NetworkStream.Я стремлюсь к максимальной скорости, поэтому я хочу минимальных задержек.Частота не контролируется, поэтому я хотел бы использовать бесконечный цикл в моих клиентах, который использует NetworkStream.Read для чтения данных, их обработки, а затем повторения.

Моя проблема в том, что иногда, если два пакета отправляются очень быстро, а у клиента медленное интернет-соединение, два пакета будут приниматься в виде непрерывного потока, что приведет к необработанным данным.Полу-решение, которое я нашел (в основном для подтверждения того, что это действительно ошибка), должно иметь небольшую задержку после / перед каждой передачей, используя System.Threading.Thread.Sleep(100), но не только я нахожу Sleep неудачное решение, оно несовместимо, так какэто также замедляет работу клиентов с хорошим соединением, и проблема может сохраняться при еще худшем соединении.

Я хотел бы, чтобы сервер отправлял разрыв между каждой передачей, обеспечивая разделение независимо от того,скорости интернета, так как NetworkStream.Read должен завершиться после окончания текущего непрерывного потока.Я не очень хорошо понимаю работу NetworkStream и понятия не имею, как выглядят несколько байтов пустого потока или как его можно реализовать.Есть идеи?

Ответы [ 2 ]

0 голосов
/ 27 мая 2018

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

Используйте UDP и реализуйте регулирование на принимающей (то есть клиентской) стороне - выбрасывая данные, если вы отстаете.

0 голосов
/ 27 мая 2018

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

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

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

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

...