Как заставить процесс передавать данные по протоколу UDP вместо TCP?

Как заставить процесс передавать данные по протоколу UDP вместо TCP?

Я запускаю процесс ffserver на машине Linux, чтобы добиться потоковой передачи видео черезffmpeg. Однако при потоковой передаче видео есть задержка.файл конфигурации ffserverЯ определяю Port 8090.

Командаnetstat -tulnapдает мне это:

root@beagleboard:/etc# netstat -tulnap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address               Foreign Address             Stat                                                                             e       PID/Program name
tcp        0      0 0.0.0.0:68                  0.0.0.0:*                   LIST                                                                             EN      654/pump
tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LIST                                                                             EN      662/portmap
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LIST                                                                             EN      698/dropbear
tcp        0      0 0.0.0.0:8090                0.0.0.0:*                   LIST                                                                             EN      744/ffserver
tcp        0     52 192.168.1.104:22            192.168.1.111:10838         ESTA                                                                             BLISHED 724/dropbear
udp        0      0 0.0.0.0:514                 0.0.0.0:*                                                                                                            703/syslog-ng
udp        0      0 0.0.0.0:111                 0.0.0.0:*                                                                                                            662/portmap
udp        0      0 0.0.0.0:60628               0.0.0.0:*                                                                                                            709/avahi-daemon: r
udp        0      0 0.0.0.0:5353                0.0.0.0:*                                                                                                            709/avahi-daemon: r

Как вы видите, процесс ffserver использует протокол tcp для передачи, и я подозреваю, что это является причиной задержки потокового видео. Как заставить процесс использовать протокол udp? Стоит ли мне сменить порт?

решение1

Вы не можете просто заставить программу использовать UDP вместо TCP, не переписывая части самой программы. Эти протоколы слишком различны, чтобы быть взаимозаменяемыми.

  • TCP ориентирован на поток (получатель видит все как непрерывный поток в том же порядке, в котором отправитель его выводит); UDP ориентирован на дейтаграммы (каждая дейтаграмма отправляется в отдельном пакете, и они даже могут быть переупорядочены).

  • TCP имеет управление потоком, поэтому отправитель (или ОС отправителя) точно знает, как быстро он должен отправлять данные, не переполняя канал или не влияя существенно на другие соединения. UDP ничего из этого не делает — плохо «заставленная» программа может начать отправлять гигабайты данных в секунду по UDP, независимо от скорости канала.

  • TCP имеет повторную передачу, поэтому если пакет теряется в середине (например, из-за перегрузки сети или других проблем), он будет отправлен повторно. Если протокол зависит от надежного транспорта, и вы заставляете его работать через UDP, соединение может полностью оборваться, как только хотя бы один пакет будет потерян. (И пакетыволя(Заблудитесь; см. пункты № 1 и № 2 выше.)

решение2

Как уже упоминалось, UDP и TCP — это принципиально разные протоколы.

Однако, если выдолженДля передачи данных по протоколу UDP вместо TCP можно использовать средство ретрансляции, напримерсокат. Вы можете настроить socat для прослушивания TCP-соединения и пересылки содержимого TCP-потока как UDP-потока на другой хост. Если другой хост ожидает TCP-трафик, вы можете использовать другой экземпляр ретранслятора для обратного преобразования в TCP. Это уберет поведение повторов и подтверждений из соединения хост-хост. Повторы и подтверждения все еще будут присутствовать между локальным ретранслятором и локальным приложением, но вы вряд ли увидите повторы на локальном петлевом соединении.

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

решение3

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

Для эффективного сжатия видео вам придется использовать предиктивное кодирование (см.эта статья в Википедии).

Предиктивные кодировки в основном вычисляют изображения из более ранних или более поздних изображений. Это имеет следующие последствия:

  1. Если вы используете много P-кадров (вычисленных из более ранних кадров), вы получите задержку перед отображением видеоначинается, поскольку клиенту приходится ждать следующего полного видеокадра (I-кадра). Однако, как только поток установлен, вы можете смотреть видео относительно без задержек.

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

Для большинства кодеков вы можете настроить использование B- и P-кадров в соответствии с вашими потребностями, однако существует компромисс между задержкой и эффективностью сжатия.

Если у вас достаточная пропускная способность, вы также можете использовать кодек без B-/P-кадров, напримерMJPEG

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

Связанный контент