Como forçar a transmissão de um processo por UDP em vez de TCP?

Como forçar a transmissão de um processo por UDP em vez de TCP?

Estou executando um processo ffserver em uma máquina Linux, para obter streaming de vídeo viaffmpeg. No entanto, há um atraso na transmissão de vídeo. Sobrearquivo de configuração do ffserverEu defino Port 8090.

Comandonetstat -tulnapme dá isso:

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

Como você pode ver, o processo ffserver usa o protocolo tcp para transmitir e suspeito que esse seja o motivo do atraso no streaming de vídeo. Como posso forçar o processo a usar o protocolo udp? Devo mudar de porta?

Responder1

Você não pode simplesmente forçar um programa a usar UDP em vez de TCP, sem reescrever partes do próprio programa. Esses protocolos são muito diferentes para serem intercambiáveis.

  • O TCP é orientado a fluxo (o receptor vê tudo como um fluxo contínuo na ordem exata em que o remetente o envia); O UDP é orientado a datagramas (cada datagrama é enviado em um pacote separado e pode até ser reordenado).

  • O TCP tem controle de fluxo, de modo que o remetente (ou o sistema operacional do remetente) sabe exatamente com que rapidez deve enviar os dados sem transbordar o link ou afetar significativamente outras conexões. O UDP não faz nada disso – um programa mal “forçado” pode começar a enviar gigabytes de dados por segundo através do UDP, independentemente da velocidade do link.

  • O TCP possui retransmissão, portanto, se um pacote for descartado no meio (por exemplo, porque a rede está sobrecarregada ou com outros problemas), ele será reenviado. Se o protocolo depender de um transporte confiável e você forçá-lo a passar pelo UDP, a conexão poderá morrer completamente assim que pelo menos um único pacote for perdido. (E pacotesvaise perder; veja os pontos 1 e 2 acima.)

Responder2

Como outros mencionaram, UDP e TCP são protocolos fundamentalmente diferentes.

No entanto, se vocêdevetransportar dados por UDP em vez de TCP, você pode usar uma ferramenta de retransmissão comosocat. Você pode configurar o socat para escutar uma conexão TCP e encaminhar o conteúdo do fluxo TCP como um fluxo UDP para outro host. Se o outro host estiver esperando tráfego TCP, você poderá usar outra instância da retransmissão para converter novamente para TCP. Isso removerá o comportamento de repetição e confirmação do link de host para host. Novas tentativas e confirmações ainda estarão presentes entre a ferramenta de retransmissão local e o aplicativo local, mas é improvável que você veja novas tentativas em um link de loopback local.

No entanto, é improvável que isso resolva seu problema de atraso. Se o seu aplicativo for criado para usar TCP em vez de UDP, ele poderá não ser tolerante com pacotes descartados e, nesse caso, esse hack poderá causar comportamento instável.

Responder3

A menos que você esteja usando conexões muito lentas, o problema de atraso provavelmente se deve ao seu codec de vídeo.

Para compactar vídeo com eficiência, você terá que usar codificações preditivas (consulteeste artigo na Wikipédia).

As codificações preditivas basicamente calculam imagens de imagens anteriores ou posteriores. Isto tem as seguintes implicações:

  1. Se você usar muitos quadros P (calculados a partir de quadros anteriores), você terá um atraso antes da exibição do vídeocomeça, porque o cliente precisa aguardar o próximo quadro de vídeo completo (I-frame). No entanto, uma vez estabelecida a transmissão, você poderá assistir ao vídeo relativamente sem atrasos.

  2. Se você usar quadros B (calculados a partir de imagens anteriores e posteriores), você terá um atraso muito grande: além do atraso inicial acima, o cliente terá que esperar o próximo quadro I para iniciar a reprodução do último quadro I. -quadro. Isso introduzirá atraso (o cliente reproduz o vídeo visivelmente mais tarde do que o servidor grava/envia, geralmente muitos segundos). Se você estiver codificando o vídeo em tempo real, também terá um atraso do servidor – ele precisará aguardar o próximo quadro I para enviar tudo a partir do quadro I anterior.

Para a maioria dos codecs, você pode ajustar o uso de quadros B e P de acordo com suas necessidades, no entanto, há uma compensação entre atraso e eficiência de compactação.

Se você tiver largura de banda suficiente, também poderá usar um codec sem quadros B/P, comoMJPEG

Outro motivo para um atraso seria o buffer do lado do player, para que você não tenha distorções se houver uma transmissão de rede instável. Muitos reprodutores de vídeo permitem ajustar os tamanhos do buffer.

informação relacionada