O UDP ainda é melhor que o TCP para jogos em tempo real com muitos dados?


71

Eu sei que o UDP geralmente é recomendado para jogos multiplayer em tempo real com alto uso de dados.

A maioria dos artigos tem vários anos de serviço, e como ~ 80% de todos os dados transmitidos na Internet são TCP, muita otimização deve ter sido feita para o TCP.

Isso me faz pensar: o UDP ainda é superior em termos de velocidade e latência? Otimizações recentes de TCP poderiam ter feito um desempenho melhor do que o UDP?


25
Com o UDP, não há garantia de que seus pacotes serão recebidos ou mesmo solicitados, apenas isso torna o UDP mais rápido que o TCP.
Nathan

4
@KaareZ, o que você quer dizer com implementação mais rápida?
Nathan

2
@nathan É mais fácil desenvolver sua aplicação com TCP do que com UDP. Quero saber se todas as otimizações de TCP fizeram do TCP uma opção melhor em termos de desempenho.
precisa saber é

3
@ KaareZ eu não sou um especialista, mas vamos pensar sobre isso. Como o TCP poderia ser melhor em termos de desempenho e ainda ser um protocolo confiável? Você não pode ter tudo. TCP é feito para confiabilidade. A verdadeira questão é por que você gostaria de usar o TCP no seu jogo?
Nathan

7
O UDP é melhor que o TCP se, e somente se, você puder (= programador de rede de baixo nível experiente) reimplementar apenas os recursos TCP necessários dentro dele com eficiência. Eliminando os recursos TCP desnecessários para desempenho.
Wondra

Respostas:


119

Não, o UDP ainda é superior em termos de latência de desempenho e sempre será mais rápido, devido à filosofia dos 2 protocolos - assumindo que seus dados de comunicação foram projetados com o UDP ou qualquer outra comunicação com perda em mente.

O TCP cria uma abstração na qual todos os pacotes de rede chegam e eles chegam na ordem exata em que foram enviados. Para implementar essa abstração em um canal com perdas, ele deve implementar retransmissões e tempos limite, que consomem tempo. Se você enviar 2 atualizações no TCP e um pacote da primeira atualização for perdido, você não verá a segunda atualização até:

  1. A perda da primeira atualização é detectada.
  2. Uma retransmissão da primeira atualização é solicitada.
  3. a retransmissão chegou e foi processada.

Não importa a rapidez com que isso é feito no TCP, porque com o UDP você simplesmente descarta a primeira atualização e usa a segunda, mais nova, agora. Ao contrário do TCP, o UDP não garante que todos os pacotes cheguem e não garante que eles cheguem em ordem.

Isso exige que você envie o tipo certo de dados e projete sua comunicação de forma que a perda de dados seja aceitável.

Se você possui dados em que todos os pacotes devem chegar e os pacotes devem ser processados ​​pelo seu jogo na ordem em que foram enviados, o UDP não será mais rápido. De fato, o uso do UDP nesse caso provavelmente seria mais lento porque você está reconstruindo o TCP e implementando-o por meio do UDP. Nesse caso, você também pode usar o TCP.

EDIT - Adicionando algumas informações adicionais para incorporar / abordar alguns dos comentários:

Normalmente, a taxa de perda de pacotes na Ethernet é muito baixa, mas se torna muito maior quando o WiFi está envolvido ou se o usuário tem um upload / download em andamento. Vamos supor que temos uma perda de pacote perfeitamente uniforme de 0,01% (só ida, não ida e volta). Em um jogo de tiro em primeira pessoa, os clientes devem enviar atualizações sempre que algo acontecer, como quando o cursor do mouse gira o player, o que acontece cerca de 20 vezes por segundo. Eles também podem enviar atualizações por quadro ou em um intervalo fixo, que seria de 60 a 120 atualizações por segundo. Como essas atualizações são enviadas em momentos diferentes, elas devem / devem ser enviadas em um pacote por atualização. Em um jogo de 16 jogadores, todos os 16 jogadores enviam esses 20 a 120 pacotes por segundo ao servidor, resultando em um total de 320 a 1920 pacotes por segundo. Com nossa taxa de perda de pacotes de 0,01%, esperamos perder um pacote a cada 5,2 a 31,25 segundos.

Em todos os pacotes que recebermos após o pacote perdido, enviaremos um DupAck e, após o terceiro DupAck, o remetente retransmitirá o pacote perdido . Portanto, o tempo que o TCP requer para iniciar a retransmissão é de 3 pacotes, mais o tempo que leva para o último DupAck chegar ao remetente. Então precisamos aguardar a retransmissão chegar, portanto, no total, esperamos 3 pacotes + 1 latência de ida e volta. A latência de ida e volta é geralmente de 0 a 1 ms em uma rede local e de 50 a 200 ms na internet. Normalmente, 3 pacotes chegarão em 25 ms se enviarmos 120 pacotes por segundo e em 150 ms se enviarmos 20 pacotes por segundo.

Por outro lado, com o UDP nos recuperamos de um pacote perdido assim que obtemos o próximo pacote, perdemos 8,3 ms se enviarmos 120 pacotes por segundo e 50 ms se enviarmos 20 pacotes por segundo.

Com o TCP, as coisas ficam mais confusas se também precisarmos considerar o Nagle (se o desenvolvedor esquecer de enviar o coalescing ou não puder desativar o ACK atrasado ), evitar o congestionamento da rede ou se a perda de pacotes for ruim o suficiente para sermos responsáveis ​​por vários perdas de pacotes (incluindo perda de Ack e DupAck). Com o UDP, podemos escrever facilmente códigos mais rápidos, porque simplesmente não ligamos para ser um bom cidadão da rede, como o TCP.


Nota: O UDP pode transmitir rede local (possível vantagem) e, como o Vista exige que o administrador execute o servidor / transmissão no UDP (desvantagem) (o UAC / firewall tende a falhar ao informar que a ação do usuário é necessária).
PTwr

7
"Se você enviar 2 atualizações no TCP, e um pacote da primeira atualização for perdido" True, mas quais são as chances disso ocorrer? De acordo com pingman : "Qualquer coisa acima de 2% de perda de pacotes durante um período de tempo é um forte indicador de problemas."
Mucaho 18/04

30
@ Peter, você está esquecendo que, no TCP, todos os pacotes descartados param todos os pacotes subsequentes. Com um ping de 100 ms, pode facilmente ser de 300 a 500 ms antes que o pacote seja retransmitido e recebido, ou seja, 6 a 10 pacotes que ficam parados a cada 33 segundos. Isso definitivamente será notado em um FPS parecido com um terremoto.
BlueRaja - Danny Pflughoeft

12
Em muitas implementações de TCP, o primeiro tempo limite após uma confirmação perdida levará um segundo inteiro. Faz muito tempo. Se os pacotes forem pequenos, o UDP poderá facilmente suavizar uma ou duas transmissões perdidas, simplesmente fazendo com que cada pacote inclua dados das duas últimas atualizações, para que o aplicativo obtenha os dados necessários antes que o remetente ou o destinatário saiba que o primeiro pacote está faltando.
Supercat

23
Em um jogo como o Quake, perder o primeiro pacote é irrelevante. Em muito menos tempo que você levaria para detectar a perda e retransmitir o primeiro pacote, você já deveria ter transmitido um segundo pacote que tornaria o primeiro obsoleto de qualquer maneira. Esse é o mesmo motivo pelo qual muitos aplicativos de voz e vídeo em tempo real também usam o UDP. Se um pacote cair, você prefere perder 0,02 segundos de áudio do que atrasar todo o fluxo por um segundo inteiro ou mais. O mesmo ocorre geralmente com jogos em tempo real, pois você deseja saber onde está um objeto agora , e não há 1,5 segundos atrás.
Reirab #

19

Concordamos que o TCP e o UDP sejam protocolos criados sobre o IP , não é? IP especifica como as mensagens são entregues pela Internet, mas nada diz respeito à estrutura e formato das mensagens. Aí vêm os protocolos TCP e UDP. Eles usam propriedades de IP, mas permitem que o programador se concentre na troca de mensagens sem se preocupar com as camadas inferiores da comunicação na rede. E isso é ótimo, porque lidar com sinais analógicos diretamente nos fios seria meio doloroso.

  • O TCP fornece um conjunto de funções para enviar e receber mensagens. Ele divide nossos dados em pequenos pacotes para nós mesmos e os envia pela rede. Tudo o que nos pedem é uma porta a ser usada no soquete de rede e a mensagem real que queremos enviar. Além disso, é confiável, o que significa que, se alguns pacotes forem perdidos na rede em que são detectados, serão enviados novamente, enviando-os na mesma ordem em que deveriam chegar.

  • Por outro lado, o UDP é um protocolo orientado ao controle do usuário. Ao usar o UDP para enviar nossos datagramas , não podemos ter certeza se o datagrama chegará ao destino ou não (e queremos dizer certeza matemática aqui: quando enviamos um pacote, ele provavelmente chegará, mas não podemos ter certeza de que 100%). Além disso, quando um pacote é perdido, ele não será detectado nem enviado novamente.

Nesse ponto, o TCP pareceria a solução ideal para todos os nossos problemas. É confiável, rápido, resolve a latência de conexão para nós, acompanhando quais pacotes chegaram e quais ainda precisamos enviar.

MAS , olhe além. A única vantagem que o UDP nos dá é sua velocidade, e é exatamente isso que realmente queremos. Um pacote UDP é apenas criado, verificado e enviado sem nenhum controle específico, porque é assim que o protocolo UDP funciona. Um pacote TCP deve ser criado, rotulado, verificado e quando chega um ACK é enviado de volta para informar ao remetente "o pacote x está aqui, continue" e, quando esse sinal não é enviado, isso significa que esse pacote x deve ser enviado novamente.

Eu sei que o UDP geralmente é recomendado para jogos multiplayer em tempo real com alto uso de dados.

Sim, mas não somente. O UDP é amplamente preferido em relação ao TCP, principalmente porque sua alta velocidade é ideal para lidar com o alto envio e gerenciamento de dados. Isso acontece quando, supondo que esse jogo seja executado em uma etapa determinista (o que acontece no servidor é replicado de forma idêntica em qualquer cliente independentemente da latência da rede), um pacote de atualização é perdido e nunca chega ao seu destino. O TCP reenviou esse pacote e os pacotes a seguir são descartados porque não estão em ordem e são reenviados após o perdido. O UDP é muito mais tolerante nesse cenário: ele não se importará com esse pacote, porque as atualizações mais recentes estão chegando. A atualização perdida não é renderizada; a física do jogo é interpolada com o método de integração usado e a atualização mais recente recebida.

O TCP causa tremulação quando a latência é alta o suficiente, o UDP não:

<video style="min-width: 100% height: auto" autoplay="" preload="auto" loop="true"><source src="https://gafferongames.com/videos/deterministic_lockstep_tcp_250ms_5pc.mp4" type="video/mp4"><source src="http://173.255.195.190/cubes_deterministic_lockstep_tcp_250ms_5pc.webm" type="video/webm">Your browser does not support the video tag.</video>

Isso me faz pensar se o UDP ainda é superior em termos de velocidade e latência.

Bem, sim, é e será por muito tempo. Você pode ler mais sobre TCP vs UDP aqui .


8
O TCP usa fluxos de bytes em vez de datagramas. O UDP usa datagramas. Boas implementações de TCP manterão os pacotes que estão fora de ordem, mas nenhum conteúdo de pacote poderá ser disponibilizado para o aplicativo, a menos ou até que todos os pacotes anteriores tenham sido recebidos. Portanto, se um pacote for perdido, o remetente pode não precisar retransmitir tudo o que se seguiu ao pacote perdido, mas o aplicativo receptor não verá nada além do pacote perdido até que esse pacote seja retransmitido (quando o aplicativo ver instantaneamente o conteúdo desse pacote) pacote e os seguintes).
Supercat #

@ supercat Infelizmente, o TCP não tem como informar exatamente ao remetente quais pacotes ele recebeu e não recebeu. Ele possui apenas um mecanismo para "Recebi todos os bytes até o número de sequência x". Se o remetente retransmitir pacotes que o destinatário já recebeu, ele simplesmente ignorará as cópias.
reirab

@reirab: Eu pensei que havia algumas extensões modernas que incluíam esse recurso, embora, mesmo sem isso, eu ache que uma implementação que enviou dados até o byte # 1.050.000, mas só recebeu reconhecimento de dados de até 1.000.000, após um segundo sem ouvir qualquer confirmação de algo além de 1.000.000, comece enviando um bloco de dados de 1.000.000 a 1.000.500 ou mais e, então, aguarde uma resposta. Se receber dados de até 1.000.500, pode retransmitir mais dados; se receber dados de até 1.050.000, pode ignorar as retransmissões.
Supercat

11
@Giorgio IP não especifica absolutamente nada sobre sinais analógicos. Isso é feito na camada física. O IP opera duas camadas acima da camada de rede. O IP não se importava se os bits estavam passando por fibra, um link de satélite ou um modem dial-up de 14,4 kbps. UDP e TCP são uma camada acima do IP, na camada de transporte. Além disso, como supercat diz, o TCP apresenta uma interface de fluxo para o aplicativo, não uma interface de datagrama como o UDP.
reirab

@ supercat Hmm ... você pode estar certo sobre extensões modernas, embora certamente não faça parte do padrão TCP original. Um ACK apenas possui um número de sequência. Eu diria que uma implementação TCP normalmente começaria a retransmitir toda a janela de envio se um pacote fosse descartado em vez de esperar um RTT inteiro para cada pacote. Isso adicionaria uma enorme quantidade de latência se vários pacotes consecutivos fossem perdidos para pouquíssimo ganho.
reirab

9

TCP <- Protocolo de controle de transmissão . É feito para controlar a transmissão.

O TCP foi criado para ser um cidadão de rede bom e diplomático. Ele se concentra em tornar a rede uma boa experiência para todos e, de bom grado, diminui sua produtividade para alcançá-la. Ele se ajusta ao ambiente adicionando latência . Os motivos são, por exemplo:

  • O receptor detecta um pacote ausente e pede ao remetente que diminua a velocidade (reduza pela metade a taxa por um tempo).
  • O receptor detecta a ordem incorreta de pacotes recebidos (talvez eles tenham seguido caminhos de rede diferentes), diz ao remetente que diminua a velocidade - e, aliás, o receptor não aceitará pacotes adicionais até que o que falta esteja presente. Lidar com isso leva tempo.
  • O remetente detecta o congestionamento da rede (por exemplo, tempo de ida e volta lento), acrescenta latência.
  • O receptor não pode acompanhar a velocidade (o buffer de entrada está ficando muito cheio), solicita ao remetente que adicione latência (controle de fluxo).
  • Existe um único receptor lento (bastardo de ping alto, bebê chorão, como são chamados) entre os receptores, latência (pode ser) adicionada na família.

Além disso

  • O algoritmo de Nagle pode manter os dados do remetente em espera, até que haja mais para enviar (a fim de utilizar os quadros de dados com mais eficiência). Os dados críticos de tempo são atrasados.
  • Eu acredito que roteadores domésticos comuns com wlan podem fazer coisas inteligentes (diminuir a velocidade) para suavizar a taxa de transferência TCP entre vários clientes (a interface wlan é o gargalo, mesmo que o jogo não a use). Relaciona-se à transmissão / difusão seletiva, ou seja. "outros" dados podem diminuir sua taxa de transferência TCP.
  • O TCP ACK reconhece tudo, o que não é necessário para um ambiente de jogo. Não há sentido em aceitar cada atualização física. O suficiente para reconhecer, por exemplo, uma vez por segundo, ou similar. Se um cliente (ou servidor) fica em silêncio por mais tempo, é hora de reagir.

Apesar disso, o TCP fornece o valor mais alto para (dados transmitidos gerais) / (tempo consumido geral). Só que isso não acontece exatamente quando você quer que isso aconteça.

O UDP não faz nada disso. Dispara com a sua vontade, apenas que não se pode esperar que acerte a cada vez - e o alvo deve anunciar que "você não dispara há muito tempo, por quê?". Ainda é possível criar pacotes ACK personalizados, colocar vários registros em um único pacote, etc. E também importante, controlar o percurso da NAT. O UDP certamente é adequado para jogos com baixa demanda de latência.


11
Nota: O algoritmo do Nagle pode ser desativado, por exemplo , para linux .
Mucaho 18/04

O Nagle pode trabalhar contra (e pode ser evitado definindo todos os pacotes como "push" pelo aplicativo) enquanto o Delayed Ack trabalha a favor dos TCPs, permite que o remetente coloque mais bytes no fio até que a janela de envio esteja cheia (idealmente grande como o buffer de recebimento está do outro lado) independentemente de uma confirmação ter sido vista.
Jeff Meden

4
É um protocolo de controle de transmissão .
precisa

11
Digite essas palavras um milhão de vezes ... thx - fixo.
quer

3

Você pode comparar o primeiro diagrama da RFC 768 (UDP) com o primeiro diagrama da página 15 da RFCP 793 (TCP) .

Ambos mostram 16 bits para uma "porta de origem", seguidos por 16 bits para uma "porta de destino". Ambos mostram 16 bits para uma "soma de verificação". De acordo com a RFC 768, o “procedimento de soma de verificação do UDP é o mesmo usado no TCP”.

Enquanto o Comprimento do UDP envolve os detalhes do diagrama do UDP, o comprimento do TCP faz parte de um “pseudo cabeçalho de 96 bits” descrito nas páginas 15 e 16.

Não espere que o TCP supere o UDP. Simplesmente não é provável que isso aconteça, por várias razões. Uma é que o TCP simplesmente possui mais bits. Portanto, se o equipamento puder processar efetivamente um certo número de bits por segundo, isso permitirá mais pacotes UDP do que pacotes TCP.

A outra razão é que o “handshake de três vias” do TCP significa que o remetente deve aguardar uma resposta. Esse requisito introduz uma sobrecarga adicional que o UDP não trata. Há uma razão pela qual a maioria das suas comunicações na Internet começa com alguma comunicação UDP. O DNS básico usa o UDP porque uma solicitação e uma resposta podem ser concluídas em menos etapas do que o processo de "handshake de três vias" do TCP. O recurso do TCP de rastrear pacotes perdidos é bastante desinteressante, porque um computador pode simplesmente fazer uma nova solicitação em vez de tentar informar um sistema remoto que existe uma solicitação anterior não atendida.


Embora os resumos em inglês (como vistos em algumas outras respostas) sejam bons, apenas ter algumas descrições precisas pode ser mais simples.
TOOGAM

Você quer dizer 16 bits, não bytes!
jcaron

Oh, bobo eu. é um exemplo de por que respostas tecnicamente precisas são boas; eles são fáceis de identificar erros e ver informações corretas. Eu consertei a resposta. Obrigado @jcaron
TOOGAM

2

Considere o que está acontecendo por um momento. Para simplificar os cenários, você tem duas opções ao tentar enviar uma mudança de estado (como seu jogador acabou de mudar de direção, ou disparou uma arma, ou outro jogador acabou de disparar uma bomba):

  1. Mantenha uma sessão TCP aberta e, quando a bomba explodir, envie uma mensagem TCP a todos os jogadores (se possível, veja abaixo)
  2. Mantenha uma porta UDP ouvindo e, quando a bomba explodir, envie uma mensagem UDP a todos os jogadores, independentemente do estado da conexão

Supondo que não houvesse uma atualização necessária logo antes, o momento em que essa atualização singular chegaria em 1 x 2 não será muito diferente. É uma viagem do servidor para o cliente. Mas, digamos, em vez de apenas uma bomba explodir, você está tentando transmitir continuamente a atividade de alguém correndo por um labirinto; tecelagem, agachamento, tiro, etc. No caso do UDP, todas as ações serão enviadas em um datagrama, assim que acontecer. No caso do TCP, todas as ações serão enviadas em um pacote apenas se o servidor tiver permissão para enviar. O que diz que é permitido enviar? Ter espaço na janela TCP (assumindo que a confirmação de atraso está ativa) para que a mensagem possa ser colocada no fio. Caso contrário, ele precisará aguardar uma confirmação do cliente antes de enviá-lo.

Quanto tempo é muito longo? Quando o desenvolvimento de jogos de tiro em primeira pessoa para vários jogadores atingiu o seu nível, no final dos anos 90 e no início dos anos 2000, as conexões de baixa latência não eram comuns. Um modem dial-up teria uma latência unidirecional típica de 180ms. Esperar por uma confirmação antes de enviar outra atualização, dobrando efetivamente esse tempo para 360ms, foi doloroso; até usuários iniciantes podem definitivamente sentir a diferença. Quando as conexões de banda larga pegaram, diminuíram muito a latência, mas ela ainda persistia quando a largura de banda era escassa (geralmente em algumas áreas). Portanto, a preferência pela menor latência possível persistiu.

As modernas conexões e interconexões domésticas mudaram isso, a ponto de a latência regional, mesmo em horários congestionados do dia, estar na faixa de 15ms ou abaixo. Escolher TCP em vez de UDP seria invisível na maioria dos casos, pois a latência é "baixa o suficiente". No entanto, ainda existe a tendência de o UDP ser priorizado em relação ao TCP, devido ao seu histórico como um protocolo de baixa latência. Portanto, por enquanto (e provavelmente em algum momento no futuro) o UDP será preferido para a comunicação em tempo real.


A latência seria baixa o suficiente, exceto que, por padrão, as gravações TCP são enviadas apenas quando os dados para gravação cruzam um determinado limite ou um tempo limite (geralmente 200-1000ms). Se você precisar de TCP em um sistema de baixa latência com pouco rendimento, você deve desabilitar esse recurso e certifique-se você não escrever bytes individuais o tempo todo (por exemplo, você já não está tratando o fluxo TCP como fluxo, e você finge que está lidando com mensagens individuais). Você não precisa esperar pelo ACK, a menos que seus buffers estejam cheios, o que dificilmente acontecerá em um jogo típico em tempo real.
Luaan

11
@Luaan Enter: o sinalizador TCP PSH. Quando um aplicativo o entrega na pilha, o pacote é enviado imediatamente sem aguardar mais dados. Muitos aplicativos usam isso com sucesso (telnet e ssh, por exemplo).
21816 Jeff Meden

2

Eu sei que o UDP geralmente é recomendado para jogos multiplayer em tempo real com alto uso de dados
O UDP ainda é superior em termos de velocidade e latência? Otimizações recentes de TCP poderiam ter feito um desempenho melhor do que o UDP?

Suas suposições estão erradas. O TCP e o UDP diferem principalmente em qual modelo eles representam (datagramas não confiáveis ​​versus fluxo virtual confiável em ordem).

Eles não diferem em relação ao volume ("alto uso de dados") ou taxa de transferência. O TCP enviará tantos dados quanto o UDP, saturando facilmente o cabo físico.

Na presença de perda de pacotes, os dois diferem na latência, mas apenas nessa condição. Caso contrário, o TCP tem latência tão baixa quanto o UDP (mais ou menos algumas dezenas de nanossegundos porque a pilha de rede tem um pouco mais de lógica para fazer, mas isso é bastante negligenciável).
Há uma pequena diferença no tamanho do cabeçalho; portanto, tecnicamente, mais bytes precisam passar por fios nas linhas seriais, mas esse também é um tanto inconseqüente. Isso realmente importa apenas para transferências em massa e, portanto, é uma diferença de 0,5%. A maioria das pessoas com acesso doméstico à Internet DSL direciona todo o tráfego por ATM, o que aumenta em mais de 10% a sobrecarga do protocolo (5 bytes de controle para 48 bytes de carga útil, mais quadros parciais), e ninguém percebe.

Algumas pessoas criam confiabilidade sobre o UDP. Se for desejado algum nível de confiabilidade, mas não for necessária uma entrega estrita em ordem, isso pode dar uma pequena vantagem. No entanto, ainda é discutível se a abordagem faz muito sentido e você paga um preço alto por essa pequena vantagem.
Se você tiver clientes conectados a partir de hotéis WiFis ou outros locais "estranhos", notará que geralmente o suporte geral ao TCP é muito, muito melhor que o UDP.

Os jogos geralmente usam o UDP não porque é superior em uma das formas mencionadas acima - não é - ou porque você pode reduzir a instabilidade em meio milissegundo implementando a confiabilidade sem ordem, mas porque os jogos (como a telefonia IP) geralmente contêm muitos dados muito voláteis, como, por exemplo, atualizações de posição.
Esses dados voláteis são obsoletos com rapidez e regularidade, com o passar do tempo e com o próximo datagrama chegando. O que significa nada mais e nada menos do que você realmente não se importa muito em ser 100% confiável (ou em ordem).

Supondo que um pacote de rede seja descartado em um serviço que é executado em um ritmo constante com atualizações frequentes chegando (jogo de tiro, telefone, bate-papo por vídeo), não faz muito sentido ter o tempo limite de reconhecimento e reenviar o pacote e, enquanto isso congele tudo do outro lado enquanto aguarda a chegada do pacote reenviado. Isso é muito perturbador e não é bom.

Em vez disso, basta considerar o pacote perdido e seguir em frente, levando os dados do próximo pacote que o compõe e, enquanto isso, o melhor possível, ocultar o fato de que um pacote foi perdido do usuário. Interpolação, acerto de contas morto, você escolhe.

Observe pela maneira como a perda de pacotes é uma condição normal. Embora o IP seja geralmente "bastante confiável", os pacotes que são descartados ocasionalmente podem acontecer e acontecerão . Enquanto os pacotes perdidos são normalmente bastante raros (<1% aqui), não é algo extraordinário ou teórico, ou uma indicação de que algo está quebrado. É perfeitamente normal.
Toda transferência em massa TCP necessariamente inclui pacotes perdidos, por exemplo (é assim que o controle de congestionamento funciona).


2

Em um MPG de alta largura de banda, você não se importa se perdeu um pacote, fornecendo a localização e a saúde do monstro # 425, porque estará recebendo outra atualização em uma fração de segundo. Este é um exemplo em que o UDP faz com que o TCP pareça estúpido por fazer você esperar por dados obsoletos instantaneamente.

Nesse mesmo jogo, você deseja que os patches apareçam exatamente como foram projetados. O TCP já possui os recursos "diga-me se falhar", facilitando novas tentativas automáticas e falhas verificadas. Você pode fazer isso no UDP, mas por que recriar a tecnologia?

Aqui está uma descrição simples do que está acontecendo.

UDP - Isolar o pedaço O'data.
Faça um pacote.
Encapsular em IP.
Enviá-lo.

TCP - isole um fluxo de dados.
Faça um pacote da frente do fluxo.
Encapsular em IP.
Aguarde espaço na janela TCP.
Enviá-lo.
Mantenha a remessa até que um recibo seja recebido ou exceda o tempo limite.
Permaneça na janela TCP até que um recibo seja recebido ou o tempo limite.

O envio significa apenas que ele passou pela NIC local, não mais.

Uma recepção de recibo TCP garante a recepção de dados e libera espaço na janela para o próximo pacote.

Reenviar (ligeiramente) aumenta a probabilidade de recebimento eventual.

Pacotes TCP são remontados do outro lado como um fluxo ordenado de dados. Pacotes UPD são recebidos como pacotes distintos. O protocolo não preserva a ordem.

O TCP é bom para enviar dados necessários e grandes quantidades ordenadas de dados. O TCP fornece notificação de uma falha persistente. O TCP se auto-acelera através de tubos bloqueados (ref: window). O TCP possui handshakes para diminuir a inicialização. O TCP requer uma "conexão" antes da transmissão.

O UDP apenas coloca os dados em conexão e permite prosseguir sem esperar janelas e retransmissões. O UDP enviará os dados a toda velocidade para um tubo obstruído, independentemente da quantidade de dados perdidos.

Projetei e escrevi um UDP Multicast File Transport Utility aplicado comercialmente. Eu trabalhei em pilhas de IP. Isso é apenas básico, sem minúcia. Explicar "soquetes, MTUs e outros brinquedos divertidos" foi um pouco além do que seria útil para essa pergunta.

Ps (não consigo adicionar comentários para responder aos comentários) O UDP também é bom para dados desejáveis, mas não necessários. A Correção de erro de encaminhamento é um exemplo disso, muitos pacotes desnecessários, mas desejáveis.


3
Seu ponto de vista sobre dados "obsoletos" é bom. O TCP é bom para dados "mais vale tarde do que nunca", mas o UDP é bom para dados que serão úteis se chegarem rapidamente ao destino, mas inúteis se não chegarem.
Supercat

1

Todos os roteadores otimizados para TCP fizeram o TCP ter um desempenho melhor que o UDP?

Mais uma pergunta é: "dados pesados" significam que você frequentemente carrega cenas?

Se sim, pode ser necessário enviar grandes quantidades de dados (> 1k) intensivamente, nos quais o TCP pode ser muito mais eficiente, porque especialmente no lado do servidor, as NICs fornecerão várias descargas no mesmo lote de ciclos. Um aplicativo de espaço do usuário pode emitir gravações grandes com TCP enquanto estiver no UDP, uma tentativa de enviar mais do que bytes de tamanho de cabeçalho MTU causará fragmentação de IP e outras sobrecargas que prejudicarão o desempenho


É um jogo "voxel", então sim, ele precisará enviar muitos dados da cena.
precisa saber é

@KaareZ Bem, provavelmente você deseja enviar essas mensagens como individuais independentes nesse caso, com seus próprios mecanismos de retransmissão. O Minecraft começou no TCP e era praticamente impossível de jogar pela internet; a mudança para o UDP foi uma ocasião feliz para a maioria das pessoas. A idéia principal é que, quando você envia 20 blocos de dados de voxel e o primeiro é "perdido", não deve impedir que os outros 19 blocos sejam exibidos assim que você obtiver os dados; quando você achar que o primeiro está faltando, você retransmitirá. No TCP, todos esses 19 são paralisados ​​no mínimo e retransmitidos na pior das hipóteses.
Luaan

2
O @Luaan Minecraft não mudou para o UDP para a jogabilidade real. Até as versões mais recentes ainda usam TCP. Nenhuma ocasião feliz ... :( A única parte do Minecraft que usa UDP é a lista de servidores, o ping servidores individuais e determinar se eles estão online.
camerondm9

1

Nem o UDP ou o TCP (ou qualquer outra variante) são superiores , nem mesmo em termos de velocidade / latência. Sua escolha deve ser feita dependendo dos requisitos do seu aplicativo. Para fazer isso, você deve comparar os recursos que cada protocolo oferece, percebendo que mais recursos implicam mais sobrecarga. Portanto, se o objetivo é minimizar a latência ou maximizar a velocidade, você deve escolher um protocolo com o mínimo de recursos possível, mas mantendo os recursos essenciais necessários para atender aos seus requisitos.

Uma comparação de protocolos

De um modo geral, o UDP (User Datagram Protocol) oferece a menor quantidade de recursos. É simplista o fato de você enviar dados sem qualquer tipo de recebimento / reconhecimento.

Por outro lado, o TCP (Transmission Control Protocol) oferece a maior quantidade de recursos necessários para uma comunicação conectada e confiável. Uma comunicação TCP envia duplicados ou mais de pacotes e os marca com informações sobre pedidos. Após o recebimento no destino, um ACK (reconhecimento) deve ser enviado de volta, juntamente com as informações sobre quais pacotes foram perdidos, para que o remetente original possa reenviar esses pacotes perdidos. Se bem me lembro, até os pacotes ACK podem precisar de reconhecimento pela confiabilidade adequada.


Exemplo: chamada em conferência do Skype

Para uma teleconferência do Skype, não é importante garantir que todos os dados de vídeo e áudio sejam enviados / recebidos de maneira confiável. Atualmente, o UDP faz um excelente trabalho ao minimizar a perda de pacotes. O importante é saber que não há absolutamente nenhuma garantia no UDP se a transmissão foi ou não bem-sucedida. Para dados de áudio / vídeo em uma teleconferência, o UDP é uma escolha adequada, porque nos preocupamos mais em obter dados em tempo real (ou seja, os mais recentes). Se alguns pacotes forem perdidos aqui e ali, isso não interromperá a comunicação de maneira dramática.

No entanto, em uma chamada em conferência, as pessoas podem enviar mensagens instantâneas (mensagens instantâneas) ou arquivos. Nesses casos, a confiabilidade é um requisito necessário para garantir que arquivos e mensagens não sejam corrompidos ou perdidos. Para mensagens instantâneas, talvez você não precise do estado conectado que o TCP fornece. Um protocolo intermediário, como o RUDP (UDP confiável), pode ser suficiente. No entanto, para arquivos, pode ser necessário ter o estado conectado que o TCP fornece.


Opções de implementação

Se você tem um aplicativo complexo ou precisa otimizar sua comunicação, é benéfico começar com uma comunicação UDP. Depois, você pode adicionar todos os recursos necessários na parte superior. Isso lhe dará o máximo controle sobre sua comunicação em rede.

Se você tiver um aplicativo simples onde a otimização não é necessária, considere optar por um padrão (UDP ou TCP) para atender às suas necessidades. Isso permitiria que você passasse para assuntos mais importantes.


1

Notei muitos comentários em que as pessoas acreditam que os pacotes TCP são maiores que os pacotes UDP. Não confie apenas em mim, leia a documentação. O protocolo é o seguinte: alguns bytes para o cabeçalho Ethernet (tipo de mensagem de 2 bytes, MAC de 48 bits, 6 bytes) (para Wifi, o cabeçalho pode ser diferente) 20 bytes para IP 20 bytes para TCP ou UDP x bytes para os dados x variação de 0 a cerca de 1500 (consulte MTU) Por fim, a soma de verificação para garantir que não ocorram danos nesse pacote Ethernet.

O TCP permite enviar pacotes "stream" maiores de cerca de 64K. Este bloco "grande" é realmente dividido em muitos pacotes Ethernet menores.


Você está tentando sugerir que os cabeçalhos UDP e TCP são do mesmo tamanho?
Cameron
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.