O protocolo TCP é bom o suficiente para jogos multiplayer em tempo real?


57

Naquele dia, as conexões TCP pela conexão discada / ISDN / banda larga lenta resultavam em jogos irregulares e atrasados ​​porque um único pacote descartado resultava em uma ressincronização. Isso significava que muitos desenvolvedores de jogos tiveram que implementar sua própria camada de confiabilidade em cima do UDP, ou usaram o UDP para mensagens que poderiam ser descartadas ou recebidas fora de ordem e usaram uma conexão TCP paralela para obter informações confiáveis.

Dado que o usuário médio tem conexões de rede mais rápidas agora, um jogo em tempo real, como um FPS, oferece bom desempenho em uma conexão TCP?


Respostas:


36

Eu diria que não. As informações espaciais dos objetos do jogo precisam ser o mais rápido possível e, para isso, é melhor usar o UDP, porque a confiabilidade não é 100% essencial. Mesmo em conexões modernas, o UDP ainda é lento o suficiente para que você precise fazer algumas considerações especiais sobre interpolação e coisas do tipo. Mesmo apenas em termos da quantidade de dados transferidos, o TCP adicionaria uma sobrecarga significativa a isso.

No entanto, o TCP é perfeitamente aceitável para coisas que não são em tempo real, como negociação para vários jogadores, mensagens de bate-papo, atualizações de pontuação etc.


7
Sean está praticamente no dinheiro. Se, por acaso, você estiver desenvolvendo um jogo em C # /. NET (você sabe que deseja!), Eu achei a Biblioteca de Rede Lidgren ( code.google.com/p/lidgren-library-network ) uma ótima opção . boa escolha. Ele ainda fornece mensagens ordenadas e confiáveis ​​por UDP, caso você precise.
Mike Strobel

2
Não é aconselhável misturar TCP e UDP; Como resultado do modo como o TCP executa o controle de fluxo, ele pode induzir a perda de pacotes. (fonte: isoc.org/INET97/proceedings/F3/F3_1.HTM )
Jason Kozak

4
Também é importante ter em mente que, em alguns casos, seus usuários finais estarão sentados atrás de ISPs que bloqueiam o tráfego UDP, têm configurações de roteador que impedem o tráfego UDP ou estão em uma situação em que o uso do UDP é inferior ao ideal. Nesses casos, se o seu jogo puder suportá-lo, é possível voltar à comunicação TCP.
Charles Ellis

outro ponto + para UD é que o seu naturalmente pacote orientado, você tem que imitar isso em TCP se necessário (boilderplatecode), infelizmente, os protocolos mais modernos não são suportados pelo Windows (isso é uma merda)
Quonux

11

Como o Flash não suporta UDP, olhando para jogos em Flash para vários jogadores, você pode ter uma boa idéia do que é possível com o TCP / IP e o que não é. Basicamente, você pode criar jogos em tempo real, desde que eles não dependam de tempos de resposta extremamente rápidos. Alguns exemplos:

http://www.xgenstudios.com/play/stickarena

http://everybodyedits.com/

Se você tem a opção de usar o UDP, você realmente deveria, mas com o Flash você infelizmente não consegue essa opção.


8

Depende.

Jogos como World of Warcraft usam o TCP para sua comunicação, porque você evita muitos problemas usando-o. Como resultado, pode haver um ping mais alto, mas, para muitos jogos, isso é aceitável. Você precisa fazer interpolação espacial, mesmo quando você usa o UDP como seu protocolo.


11
Não é apenas ping. Há uma razão pela qual não há colisões jogador-jogador no WoW. Seria muito difícil fazer o bem. O WoW pode usar o TCP, porque onde você está não importa muito. Mirar e atacar não depende da posição real do monstro ou jogador inimigo. Se você se importa com essas coisas, o TCP prejudicará a experiência de jogo.
Nuoji

6

Se a arquitetura do seu cliente / servidor estiver limpa, a camada de transporte (quase) não importará.

O TCP tem algumas desvantagens, mas elas são facilmente contornadas.

Então, sim, TCP e um cérebro são tudo o que você precisa.

Com configurações de rede comuns (proxies, firewalls, etc) hoje, o UDP é praticamente inútil para todos, exceto para jogos locais (leia-se: LAN).


7
Se você votou negativamente, por favor, deixe um comentário. Usamos o TCP e nunca tivemos um único problema.
Andreas

3
Não vejo a relevância das configurações de rede comuns nisso. Os firewalls geralmente interferem apenas nos servidores de hospedagem, mas mesmo assim, independentemente do protocolo, enquanto os proxies aumentam o risco de pacotes atrasados ​​ou descartados, tornando o UDP muito mais útil do que em uma rede local. As desvantagens do UDP podem ser amplamente contornadas por meio de verificações de integridade, mas você não pode retirar recursos do TCP para torná-lo mais rápido.
Marcks Thomas

11
Você precisa mencionar Nagles . Eu sempre esqueço que essa é a causa raiz do TCP (os pacotes de buffers do Nagle no cliente / servidor, basicamente os "retêm" do seu jogo e introduzem um atraso adicional).
bobobobo

Existem várias razões pelas quais você deve usar o UDP em vez do TCP se a latência for uma preocupação. Se você não se importa com a latência e / ou é capaz de fazer previsões suficientes no lado do cliente, o TCP pode ser suficiente. No caso de jogos em tempo real. Esqueça o TCP.
Nuoji

6

É perfeitamente aceitável usar TCP em vez de UDP - se você desativar o algoritmo do Nagle .

Depois de desligar o Nagle, você tem a maior velocidade do UDP e poderá fazer um jogo de reação de contração . Na verdade, eu fiz esse jogo usando o TCP no Flash:

http://2dspacemmo.wildbunny.co.uk

Espero que ajude!


Aplicativo não operacional no seu link, senhor.
Engenheiro

Link completamente girado, senhor. Eu recebo um teste do servidor Apache.
Gustavo Maciel

4

Para jogos de FPS, sempre usamos UDP. Especialmente se você estiver fazendo um jogo de tiros onde pings importam.


4

Depende do tipo de jogo.

Alguns jogos, como o RTS, jogam muito melhor com o TCP e geralmente usam o TCP o tempo todo.

O verdadeiro problema com o TCP é que, se você obtiver perda de pacotes - mesmo que pequena quantidade -, a conexão "travará" até que ocorra a retransmissão. O sistema operacional não pode fornecer dados fora de ordem para o aplicativo (isso quebra as garantias do TCP, mas também, o TCP não mostra os limites do quadro do aplicativo). A paralisação da conexão significa que os dados atrasados ​​chegam posteriormente. Mas em um jogo (por exemplo) de FPS, dados desatualizados são inúteis.

Com o UDP, o aplicativo escolhe o que faz com dados atrasados ​​ou fora de ordem. Ele pode (e para um jogo como o FPS, geralmente faz) ignorar dados antigos e apenas pegar os mais recentes. Um pacote perdido ocasionalmente não atrasa os pacotes subsequentes. Se um pacote atrasado chegar, ele poderá ser ignorado pelo jogo.


Observe que sua implementação precisará lidar com o aspecto de descartar pacotes atrasados, pois o UDP a tratará como um datagrama recebido.
Guvante

3

Não aceite apenas uma resposta direta "sim ou não, porque eu disse isso" aqui, pois você pode estar se abrindo para ter que enfrentar um monte de problemas com o UDP que na verdade você não precisa enfrentar.

Nenhuma das outras respostas aqui afirma a maneira óbvia de provar isso.

Veja alguns fatos simples

  • Um cabeçalho IP tem 20 bytes, independentemente do protocolo usado.
  • Os cabeçalhos UDP têm 4 bytes
  • Os cabeçalhos TCP são 20 bytes

Portanto, toda vez que você envia uma mensagem de 1 byte abaixo da linha, você realmente enviou 25 ou 41 bytes, dependendo do protocolo, assumindo que um cabeçalho IP também é necessário.

fontes:

Meu conselho

Leve a sua situação em que você precisa da interação do servidor cliente, estime o número de clientes e faça as contas com base nos dados que você realmente envia entre os 2.

Um exemplo

Digamos que eu envio 10 mensagens com 1 byte cada por atualização no meu jogo e estou atualizando em torno de 60 fps, por isso preciso enviar 60 * 10 = 600 bytes por segundo dos dados reais da mensagem + os cabeçalhos relevantes.

Agora, dependendo do jogo, eu poderia enviar tudo isso como uma única mensagem, para que minha sobrecarga da camada TCP tivesse apenas 40 bytes (efetivamente um custo de UDP de 20 bytes por segundo), não ter essa sobrecarga é um custo potencial de 600 bytes ( porque talvez seja necessário reenviar todo o fluxo de mensagens).

Se, no entanto, é de vital importância que todas as mensagens sejam enviadas por si próprias no instante em que estiverem prontas para serem enviadas, eu tenho 600 mensagens (também 600 bytes) + 40 * 600 = 24k de sobrecarga TCP ou ~ 14k de UDP por segundo 600 bytes de dados da mensagem.

Novamente, fazemos as perguntas: quão vitais são essas mensagens, com que frequência elas são e podem ser agrupadas de alguma forma para reduzir as despesas gerais?

Isso se baseia apenas em várias mensagens de byte único; normalmente, você faria algo muito diferente, mas sem saber que os dados brutos estão sendo difíceis de provar de qualquer maneira, se o TCP é mais adequado à sua situação do que o UDP.

Então, vai funcionar?

Bem, se você tem um fps típico e a posição é importante (para evitar trapaceiros ou decisões incorretas), você precisa saber que o fluxo da sua rede é realizável, mas 32 players cada transmitem esses 24k + bytes de mensagens para frente e para trás (então 768KB / s + mensagens) ... trata-se de uma linha de banda larga de 10mb / s apenas para cabeçalhos individuais, com base no envio de pelo menos 1 mensagem por quadro de cada cliente para todos os outros clientes através de um servidor.

Obviamente, você não codificará o servidor e o cliente para trabalhar dessa maneira e os tamanhos das mensagens provavelmente serão muito maiores e provavelmente um pouco menos frequentes que 1 byte por quadro na maioria das situações, por isso é difícil dizer sem ver o mundo real exemplo "estes são os dados que preciso enviar".

O meu caso

No meu caso, fiz uma ligação que é uma sobrecarga razoável, mas isso se baseia na maneira como construo meus fluxos de mensagens, para que não haja sobrecargas enormes em comparação com alguns designs.

O TCP funciona bem e eu tenho uma estrutura de servidor e cliente MMO escalonável, mas não preciso transmitir muitos dados em um quadro ou muitos pacotes pequenos, porque posso agrupar minhas chamadas.

para outros: o TCP simplesmente não funciona, e eles só podem usar o UDP, mas precisam aceitar que isso não lhes dará garantias sobre o que recebem (garantia de pedidos / chegada).

Outras considerações

Muitos mecanismos de jogos mal codificados lidam com tudo no segmento principal da CPU, de modo que a CPU geralmente recebe apenas uma quantidade muito pequena de tempo para lidar com o código de rede, uma implementação decente do servidor e do cliente seria inteiramente assíncrona e possivelmente pressionaria e puxe mensagens em lotes.

Existem algumas boas bibliotecas de rede por aí, mas, como visto aqui, muitas parecem ter uma opinião de que o UDP é "apenas melhor", bem como fator para suas próprias necessidades primeiro e que pode não ser o caso, e encontrar uma biblioteca que não fator nas coisas da maneira que você faz pode resultar em uma configuração de TCP mal codificada em comparação com a variante UDP na mesma lib (só estou dizendo que vi isso e testes de carga provaram isso).

Crie algo primeiro, uma base técnica dos dados que você deseja enviar e teste-os, depois faça as contas para escaloná-los; na pior das hipóteses, teste-os com a implantação em uma nuvem e faça com que 50 computadores executem um cliente de teste para ver se ele pode manipular seu limite de 32 jogadores por jogo (ou quaisquer limites que você possa ter).


2

Acho que não ... Jogos em que a transferência de dados é muito frequente (ao mover o mouse ou pressionar a tecla), devem usar o UDP. Ficará mesmo na LAN se o TCP for usado.

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.