Qual é a solução alternativa para o reconhecimento atrasado do TCP?

Enviei um videogame online (baseado em grade) que usa o protocolo TCP para garantir uma comunicação confiável em uma topologia de rede servidor-cliente. Meu jogo funciona razoavelmente bem, mas sofre com uma latência maior que o esperado (jogos TCP semelhantes no gênero parecem fazer um trabalho melhor em manter a latência em um nível mínimo).

Ao investigar, descobri que a latência é inesperadamente alta para clientes executandoMicrosoft Windows (em oposição aMac OS X clientes). Além disso, descobri que, se um cliente Windows definirTcpAckFrequency=1 no registro e reinicia a máquina, a latência se torna normal.

Parece que meu design de rede não levou em consideração o atraso no reconhecimento:

Um design que não leva em consideração a interação deatraso no reconhecimento, o algoritmo Nagle e o buffer Winsock podem afetar drasticamente o desempenho. (http://support.microsoft.com/kb/214397)

No entanto, estou achando quase impossível levar em conta o reconhecimento atrasado no meu jogo (ou em qualquer outro jogo). De acordo com o MSDN, a pilha TCP da Microsoft usa os seguintes critérios para decidir quando enviar um ACK nos pacotes de dados recebidos:

Se o segundo pacote de dados for recebido antes que o timer de atraso expire (200ms), o ACK será enviado.Se houver dados a serem enviados na mesma direção que o ACK antes que o segundo pacote de dados seja recebido e o temporizador de atraso expire, o ACK será transferido para o segmento de dados e enviado imediatamente.Quando o temporizador de atraso expirar (200 ms), o ACK é enviado.

(http://support.microsoft.com/kb/214397)

Lendo isso, presume-se que a solução alternativa para reconhecimento atrasado na pilha TCP da Microsoft seja a seguinte:

Desative o algoritmo Nagle (TCP_NODELAY).Desative o buffer de envio do soquete (SO_SNDBUF= 0), para que uma chamada parasend pode-se enviar um pacote.Ao ligarsend, se não se espera que mais dados sejam enviados imediatamente, ligue parasend novamente com um byte único de dados que serão descartados pelo receptor.

Com essa abordagem, o segundo pacote de dados será recebido pelo receptor aproximadamente ao mesmo tempo que o pacote de dados anterior. Como resultado, oACK deve ser enviado imediatamente do destinatário ao remetente (emulando o queTcpAckFrequency=1 faz no registro).

No entanto, nos meus testes, isso aumentou a latência em cerca de metade do que a edição do Registro faz. o que estou perdendo?

P: Por que não usar UDP?

UMA: Eu escolhi o TCP porque cada pacote que eu envio precisa chegar (e estar em ordem); não há pacotes que não valham a pena retransmitir se eles se perderem (ou ficarem desordenados). Somente quando os pacotes podem ser descartados / não ordenados, o UDP pode ser mais rápido que o TCP!

questionAnswers(7)

yourAnswerToTheQuestion