2015-02-23 3 views
2

Я знаю, как открыть UDP-сокет в C++, и я также знаю, как отправлять пакеты через него. Когда я отправляю пакет, я правильно его получаю на другом конце, и все работает нормально.Эффективно отправлять поток UDP-пакетов

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

Теперь мне нужно перенести большой кусок данных (скажем, 1 ГБ), и мне нужно, чтобы он был перенесен как можно быстрее. Таким образом, я разбил данные, скажем, на 512 байтов и отправил их через сокет UDP.

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

То, что я тогда делал цикл:

  • сна на некоторое время
  • Отправить кучу пакетов
  • Сон снова и так далее

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

Так есть ли какое-либо другое решение? Любое широко принятое решение? Я предполагаю, что у моего маршрутизатора есть буфер или что-то в этом роде, так что он может принимать НЕКОТОРЫЕ пакеты сразу, а затем для их обработки требуется некоторое время. Насколько велик этот буфер?

Я не эксперт в этом, поэтому любое объяснение было бы замечательным.

Обратите внимание, что по техническим причинам вообще нет Я могу использовать TCP.

+0

начать играть с [iperf] (https://iperf.fr/). посмотрите, насколько далеко вы находитесь от скорости, которую вы можете получить с помощью iperf. Это с открытым исходным кодом, чтобы вы могли видеть, что они сделали. – MehrZ

+1

Хм .. может быть, вам нужен какой-то протокол контроля потока. Вы можете использовать его в сообщениях ACK, возвращаемых одноранговым узлом, чтобы скорость отправки дейтаграммы могла быть уменьшена, если общие потери превысили некоторое значение. Такие небольшие, 512 байт, датаграммы не кажутся очень эффективными :( –

+0

Вы думали о создании своего сокета 'SOCK_SEQPACKET'? – Freddy

ответ

1

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

http://en.wikipedia.org/wiki/Flow_control_%28data%29

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

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

Это что-то вроде грубого упрощения, но я думаю, что у вас есть идея.

+0

Хорошо! На самом деле, я уже сделал такое. Пакеты I посылают контрольные суммы, они получают подтверждение, и у меня также есть идея о том, сколько пакетов, которые я отправил, в течение последней половины секунды были фактически получены другой конечной точкой. Теперь я подумал об изменении количества пакетов, которые я отправляю каждый раз, когда вызывается функция отправки(). Но как часто мне это называть? Be K - количество раз, когда я вызываю его каждую секунду, D - количество пакетов, которые я отправляю каждый раз, когда я его вызываю. Be N количество пакетов в секунду, тогда N = K * D. Но, полагаю, эффективность также зависит от D, правильно? –

+0

Я имею в виду, предположим, что я хочу отправлять 1000 пакетов каждую секунду. Я полагаю, что спать секунду, отправляя 1000 пакетов, а затем спать секунду - это не то же самое, что спать миллисекунду, отправлять пакет и снова спать. Но при очень высоком N, сохраняя D = 1 и увеличивая K, становится невыполнимым. –

+0

Более того, я даже не уверен, что сама парадигма сна - отправить - спать - отправить то, что я должен использовать. Может быть, есть готовые решения, о которых я ничего не знаю? –

Смежные вопросы