O que você usa quando precisa de um UDP confiável?

92

Se você tiver uma situação em que uma conexão TCP seja potencialmente muito lenta e uma 'conexão' UDP seja potencialmente muito não confiável, o que você deve usar? Existem vários protocolos UDP padrão confiáveis, que experiência você tem com eles?

Discuta um protocolo por resposta e se outra pessoa já mencionou aquele que você usa, considere votá-lo e usar um comentário para elaborá-lo, se necessário.

Estou interessado nas várias opções aqui, das quais TCP está em uma extremidade da escala e UDP está na outra. Várias opções confiáveis ​​de UDP estão disponíveis e cada uma traz alguns elementos de TCP para UDP.

Eu sei que muitas vezes o TCP é a escolha correta, mas ter uma lista de alternativas geralmente é útil para ajudar alguém a chegar a essa conclusão. Coisas como Enet, RUDP, etc. que são construídas em UDP têm vários prós e contras, você já os usou, quais são suas experiências?

Para evitar dúvidas, não há mais informações; esta é uma pergunta hipotética e que eu esperava que gerasse uma lista de respostas que detalhassem as várias opções e alternativas disponíveis para alguém que precisa tomar uma decisão.

Len Holgate
fonte
1
Esta pergunta parece estar fora do tópico porque é uma pesquisa de tecnologias
Dave Hillier
Aqueles que pensam que o TCP é o melhor em todos os casos, leia: en.wikipedia.org/wiki/Bandwidth-delay_product
nullptr
A Wikipedia tem uma boa tabela comparando vários aspectos de UDP, UDP Lite, TCP, Multipath TCP, SCTP, DCCP e RUDP . O SCTP oferece suporte à maioria dos recursos dessa lista.
Eugene Beresovsky
@EugeneBeresovsky Fiz uma pequena pesquisa sobre o SCTP, a maioria das informações, incluindo as respostas do SO, datadas de 2013 e anteriores. A maioria das pessoas escreveu naquela época que a adoção do SCTP era muito baixa. Eu me pergunto como é hoje? Além disso, veja este tópico stackoverflow.com/questions/1171555/…
Michael IV
@MichaelIvanov A adoção é realmente baixa. Mas se você pretende usá-lo dentro do seu data center, você não se preocupa com a adoção externa, contanto que switches e roteadores não causem problemas (o que, em um data center, não deveriam), e você tem sistema operacional e suporte à biblioteca, que pode ser um problema, conforme descrito em uma das respostas da pergunta vinculada.
Eugene Beresovsky

Respostas:

25

É difícil responder a essa pergunta sem algumas informações adicionais sobre o domínio do problema. Por exemplo, que volume de dados você está usando? Com que frequência? Qual é a natureza dos dados? (por exemplo, são dados únicos, únicos? Ou é um fluxo de dados de amostra? etc.) Para qual plataforma você está desenvolvendo? (por exemplo, desktop / servidor / incorporado) Para determinar o que você quer dizer com "muito lento", que meio de rede você está usando?

Mas em termos (muito!) Gerais, acho que você vai ter que tentar muito superar o tcp em velocidade, a menos que possa fazer algumas suposições rígidas sobre os dados que está tentando enviar.

Por exemplo, se os dados que você está tentando enviar são tais que você pode tolerar a perda de um único pacote (por exemplo, dados regularmente amostrados onde a taxa de amostragem é muitas vezes maior do que a largura de banda do sinal), então você provavelmente pode sacrificar alguma confiabilidade de transmissão, garantindo que você possa detectar corrupção de dados (por exemplo, através do uso de um bom crc)

Mas se você não pode tolerar a perda de um único pacote, você terá que começar a introduzir os tipos de técnicas de confiabilidade que o tcp já possui. E, sem colocar uma quantidade razoável de trabalho, você pode descobrir que está começando a construir esses elementos em uma solução de espaço do usuário com todos os problemas de velocidade inerentes a ela.

Andrew Edgecombe
fonte
4
Ok, vou ajustar a pergunta. Estou mais interessado nos prós e contras dos vários protocolos UDP confiáveis ​​por aí, em vez de uma resposta 'usar TCP';)
Len Holgate
9
@Andrew - é muito FÁCIL vencer o TCP em dois casos: (1) seu aplicativo tem requisitos de confiabilidade mais leves do que "todos os dados, sempre em ordem, sem duplicatas, sem fila excessiva". Ou (2) você está usando multicast. O UDP confiável é muito comum para ambientes multicast.
Tom
4
Além disso, o TCP sofre terrivelmente quando usado em uma conexão WAN (problemas de longa distância). Ora, simples. O TCP usa janelas onde os pacotes da janela devem ser ack'd. Os protocolos ACK sofrem por causa da latência devido à distância da linha. Google: WAN TCP "velocidade da luz"
Ajaxx
3
@Ajaxx, você está correto quanto a isso, entretanto, o TCP / IP faz isso propositalmente por causa do último colapso da Internet. Se você está fazendo um protocolo de alta taxa de bits sem nenhum controle de congestionamento, bem, basicamente, que vergonha. Se você possui a rede, vá à loucura.
Kevin Nisbet
2
“onde a taxa de amostragem é significativamente maior do que a taxa de nyquist” - a taxa de amostragem é sempre duas vezes a taxa de nyquist, por definição.
Steve
27

E quanto ao SCTP . É um protocolo padrão da IETF (RFC 4960)

Ele tem capacidade de agrupamento que pode ajudar na velocidade.

Atualização: uma comparação entre TCP e SCTP mostra que os desempenhos são comparáveis, a menos que duas interfaces possam ser usadas.

Atualização: um bom artigo introdutório .

filante
fonte
Isso é bom, estou mais interessado em coisas que podem ser construídas em cima de UDP em vez de em IP, mas certamente é algo que se encaixa no espaço de solução.
Len Holgate de
O SCTP tem muitos recursos excelentes (como multihoming) e com a extensão de confiabilidade parcial (RFC 3758) é uma opção incrivelmente flexível. Está incluído nas últimas versões do kernel do Linux, mas para o Windows, você terá que instalar sua própria pilha SCTP.
Andrew Johnson,
6
O SCTP pode ser encapsulado em UDP. tools.ietf.org/id/draft-ietf-sigtran-sctptunnel-00.txt
Milhas de
Obrigado Miles, esse é um link útil!
Len Holgate
1
Sim ... Mas algo que é construído em cima do UDP, em vez de no mesmo nível do UDP, provavelmente será mais fácil de implementar no espaço do usuário, pelo menos no Windows ...
Len Holgate
21

ENET - http://enet.bespin.org/

Trabalhei com o ENET como um protocolo UDP confiável e escrevi uma versão amigável de soquetes assíncronos para um cliente meu que o está usando em seus servidores. Funciona muito bem, mas não gosto da sobrecarga que o ping ponto a ponto adiciona às conexões ociosas; quando você tem muitas conexões, fazer ping em todas elas regularmente é muito trabalhoso.

ENET lhe dá a opção de enviar múltiplos 'canais' de dados e para que os dados enviados não sejam confiáveis, confiáveis ​​ou sequenciados. Também inclui o ping ponto a ponto mencionado anteriormente, que atua como um keep alive.

Len Holgate
fonte
14

Temos alguns clientes da indústria de defesa que usam UDT (UDP-based Data Transfer) (consulte http://udt.sourceforge.net/ ) e estão muito satisfeitos com isso. Vejo que também tem uma licença BSD amigável.

Chris Markle
fonte
2
Você pode falar sobre seus clientes e seus casos de uso, especialmente no setor de defesa? Provavelmente não, mas vale a pena tentar. Na verdade, já expus a ideia aos meus superiores sobre o UDT em um aplicativo de transferência de arquivos, mas ainda não deu certo.
Thomas Owens
10

RUDP - Protocolo de Datagrama de Usuário Confiável

Isso fornece:

  • Confirmação de pacotes recebidos
  • Controle de janelas e congestionamento
  • Retransmissão de pacotes perdidos
  • Overbuffering (mais rápido do que o streaming em tempo real)

Parece um pouco mais configurável com relação a keep alives do que ENet, mas não oferece tantas opções (ou seja, todos os dados são confiáveis ​​e sequenciados, não apenas os bits que você decidir que deveriam ser). Parece bastante simples de implementar.

Len Holgate
fonte
Eu estava olhando para isso, mas não parece haver muitas implementações. Tem uma recomendação?
Nicholas
Não, desculpe. Não acabei usando no final e sempre faria uma implementação do zero.
Len Holgate
9

Como outros apontaram, sua pergunta é muito geral, e se algo é ou não 'mais rápido' que o TCP depende muito do tipo de aplicativo.

O TCP é geralmente o mais rápido possível para streaming confiável de dados de um host para outro. No entanto, se seu aplicativo faz muitos pequenos picos de tráfego e espera por respostas, o UDP pode ser mais apropriado para minimizar a latência.

Existe um meio-termo fácil. O algoritmo de Nagle é a parte do TCP que ajuda a garantir que o remetente não sobrecarregue o receptor de um grande fluxo de dados, resultando em congestionamento e perda de pacotes.

Se você precisa da entrega confiável e em ordem do TCP, e também da resposta rápida do UDP, e não precisa se preocupar com o congestionamento do envio de grandes fluxos de dados, desative o algoritmo de Nagle:

int opt = -1;
if (setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt)))
  printf("Error disabling Nagle's algorithm.\n");
smo
fonte
Como eu disse, presumindo que o TCP está em uma extremidade da escala e o UDP na outra, o que mais está lá.
Len Holgate,
Se você quiser ser pedante, a maioria dos protocolos discutidos são construídos com base no UDP.
smo em
A suposição de que o TCP está em uma extremidade e o UDP na outra é falsa. por exemplo, UDP não tem controle de fluxo, você pode facilmente enviar pacotes muito rápido, fazendo com que um roteador intermediário descarte todos eles. Então o que você faz? Ignorar os pacotes perdidos ou reenviá-los? Reenvie-os e você acabará reimplementando o TCP mais ou menos. Outra opção para comunicação confiável é o SCTP.
nos
1
Uma resposta rápida não é necessariamente igual a um alto rendimento.
Matt
1
Discordo. Quando o nagle é usado em protocolos baseados em TCP com muitos pacotes menores, ele os mescla e cria pacotes maiores. Isso causa um pequeno atraso no envio, portanto, o latecy pode aumentar ligeiramente. No entanto, a taxa de transferência pode ser menor com o nagle desligado porque mais pacotes = mais cabeçalhos de pacote = maior sobrecarga. Os pacotes descartados em uma LAN geralmente têm mais a ver com o preenchimento dos buffers de entrada. Se você tiver muitos clientes enviando dados para o mesmo host, isso pode não fazer nenhuma diferença. Não acredito que desligar e ligar o nagle vá afetá-lo na prática.
Matt
8

Qualquer um que decidir que a lista acima não é suficiente e que deseja desenvolver seu PRÓPRIO UDP confiável deve definitivamente dar uma olhada nas especificações QUIC do Google, pois isso cobre muitos casos complicados e possíveis ataques de negação de serviço. Eu não brinquei com uma implementação disso ainda, e você pode não querer ou precisar de tudo o que ele oferece, mas vale a pena ler o documento antes de embarcar em um novo design UDP "confiável".

Um bom ponto de partida para o QUIC é aqui , no Blog do Chromium.

O documento de design QUIC atual pode ser encontrado aqui .

Len Holgate
fonte
4

Se você tiver uma situação em que uma conexão TCP seja potencialmente muito lenta e uma 'conexão' UDP seja potencialmente muito não confiável, o que você deve usar? Existem vários protocolos UDP padrão confiáveis, que experiência você tem com eles?

A palavra-chave em sua frase é 'potencialmente'. Eu acho que você realmente precisa provar a si mesmo que o TCP é, de fato, muito lento para suas necessidades se você precisar de confiabilidade em seu protocolo.

Se você deseja obter confiabilidade do UDP, então basicamente irá reimplementar alguns dos recursos do TCP no topo do UDP, o que provavelmente tornará as coisas mais lentas do que apenas usar o TCP em primeiro lugar.

17 de 26
fonte
Sim, Andrew Edgecombe disse isso, mas, como eu disse, estou interessado nos prós e contras de QUAIS alternativas existem. Sem essa lista de alternativas e seus prós e contras, é difícil decidir o que é melhor.
Len Holgate,
Dada uma função de confiabilidade conhecida, às vezes um fluxo UDP pode ser ajustado manualmente para ultrapassar o fluxo TCP em seu sistema operacional. Embora raro.
Joshua
1
@ 17 de 26, concordo com Len Holgate, o TCP será mais lento do que o UDP confiável em algumas circunstâncias. Como uma rede de BDP alto, suponha que você tenha uma conexão de Internet de 1 Gbps da China para Nova York, tenho certeza de que o TCP será uma droga para usar quase toda a velocidade de 1 Gbps. TCP é melhor para a maioria das conexões na terra, mas não para redes com produto de atraso de largura de banda alta.
nullptr
4

O protocolo DCCP, padronizado no RFC 4340 , "Datagram Congestion Control Protocol" pode ser o que você está procurando.

Parece implementado no Linux .

bortzmeyer
fonte
3

Pode ser RFC 5405 , "Diretrizes de uso de UDP Unicast para designers de aplicativos" será útil para você.

bortzmeyer
fonte
2

Você considerou compactar seus dados?

Conforme declarado acima, não temos informações sobre a natureza exata do seu problema, mas compactar os dados para transportá-los pode ajudar.

filante
fonte
1
Especialmente com bibliotecas de compactação modernas. Alguns são tão rápidos quanto um mempy. por exemplo, lz4.
Matt
2

RUDP . Muitos servidores de soquete para jogos implementam algo semelhante.

Engenheiro
fonte
-3

A melhor maneira de obter confiabilidade usando UDP é construir a confiabilidade no próprio programa de aplicação (por exemplo, adicionando mecanismos de reconhecimento e retransmissão)

kushan singh
fonte