Il protocollo TCP è abbastanza buono per i giochi multiplayer in tempo reale?


57

Ai giorni nostri, le connessioni TCP su dialup / ISDN / banda larga lenta si traducevano in giochi discontinui e in ritardo perché un singolo pacchetto rilasciato provocava una risincronizzazione. Ciò significava che molti sviluppatori di giochi dovevano implementare il proprio livello di affidabilità sopra UDP, oppure usavano UDP per i messaggi che potevano essere eliminati o ricevuti fuori servizio e una connessione TCP parallela per informazioni che dovevano essere affidabili.

Dato che l'utente medio ha connessioni di rete più veloci ora, un gioco in tempo reale come un FPS può fornire buone prestazioni su una connessione TCP?


Risposte:


36

Direi di no. Le informazioni spaziali sugli oggetti di gioco devono essere il più veloci possibile, e per questo è meglio usare UDP, perché l'affidabilità non è al 100% crudiale. Anche su connessioni moderne, UDP è ancora abbastanza lento da dover fare alcune considerazioni speciali per l'interpolazione e simili. Anche solo in termini di quantità di dati trasferiti, TCP aggiungerebbe un notevole sovraccarico a questo.

Tuttavia, TCP è perfettamente accettabile per cose non in tempo reale, come la negoziazione multiplayer, i messaggi di chat, gli aggiornamenti dei punteggi, ecc.


7
Sean è praticamente sui soldi. Se, per caso, stai sviluppando un gioco in C # /. NET (sai che lo vuoi!), Ho trovato la Lidgren Network Library ( code.google.com/p/lidgren-library-network ) per essere una bella bella scelta. Fornisce anche messaggistica ordinata e affidabile su UDP, se ne hai bisogno.
Mike Strobel,

2
Non è saggio mescolare sia TCP che UDP; a causa del modo in cui TCP esegue il controllo del flusso, può causare la perdita di pacchetti. (fonte: isoc.org/INET97/proceedings/F3/F3_1.HTM )
Jason Kozak,

4
È anche importante tenere presente che in alcuni casi gli utenti finali siederanno dietro gli ISP che bloccano il traffico UDP, che hanno configurazioni del router che impediscono il traffico UDP o che si trovano in una situazione in cui l'utilizzo di UDP è tutt'altro che ideale. In questi casi, se il tuo gioco può supportarlo, è molto utile poter ricorrere alla comunicazione TCP.
Charles Ellis,

un altro punto + per UD è che è naturalmente orientato ai pacchetti, è necessario emularlo in TCP se necessario (codice boilderplatec), purtroppo i protocolli più moderni non sono supportati da Windows (fa schifo)
Quonux

11

Dato che Flash non supporta UDP, guardando i giochi multiplayer in Flash puoi avere una buona idea di cosa sia possibile con TCP / IP e cosa no. Fondamentalmente puoi creare giochi in tempo reale, purché non si basino su tempi di risposta rapidissimi. Un paio di esempi:

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

http://everybodyedits.com/

Se hai la possibilità di usare UDP, dovresti davvero, ma con Flash purtroppo non hai questa opzione.


8

Dipende.

Giochi come World of Warcraft usano TCP per le loro comunicazioni, perché si aggira molti problemi utilizzandolo. Di conseguenza potrebbe esserci un ping più alto, ma per molti giochi questo è accettabile. È necessario eseguire l'interpolazione spaziale anche quando si utilizza UDP come protocollo.


1
Non è solo ping. C'è un motivo per cui non ci sono collisioni giocatore-giocatore in WoW. Sarebbe troppo difficile fare bene. WoW può usare TCP perché la tua posizione non conta molto. Il bersaglio e l'attacco non dipendono dalla posizione reale del mostro o del giocatore nemico. Se ti interessano queste cose, TCP danneggerà l'esperienza di gioco.
Nuoji,

6

Se l'architettura client / server è pulita, il livello di trasporto (quasi) non ha importanza.

TCP presenta alcuni inconvenienti, ma questi sono facilmente aggirabili.

Quindi sì, TCP e un cervello sono tutto ciò che serve.

Con le configurazioni di rete comuni (proxy, firewall, ecc.), Oggi UDP è praticamente inutile per tutti i giochi tranne quelli locali (leggi: LAN).


7
Se voti in negativo, lascia un commento perché. Usiamo TCP e non abbiamo mai avuto un singolo problema con esso.
Andreas,

3
Non riesco a vedere la pertinenza delle configurazioni di rete comuni in questo. I firewall in genere interferiscono solo con i server di hosting, ma anche a prescindere dal protocollo, mentre i proxy aumentano effettivamente il rischio di pacchetti ritardati o eliminati, rendendo UDP molto più utile di quanto sarebbe su una rete locale. Gli svantaggi di UDP possono essere in gran parte elusi eseguendo personalmente i controlli di integrità, ma non è possibile estrarre funzionalità dal TCP per renderlo più veloce.
Marcks Thomas,

1
Devi menzionare Nagles . Dimentico sempre che questa è la causa principale per cui TCP è malvagio (i pacchetti di buffer di Nagle su client / server, fondamentalmente "trattenendoli" dal gioco e introducendo ulteriore ritardo).
bobobobo,

Esistono diversi motivi per cui è necessario utilizzare UDP anziché TCP se la latenza è un problema. Se non ti interessa la latenza e / o sei in grado di fare abbastanza previsione sul lato client, allora TCP può essere sufficiente. Nel caso di giochi in tempo reale. Dimentica TCP.
Nuoji,

6

È perfettamente accettabile utilizzare TCP anziché UDP - se si disattiva l' algoritmo di Nagle .

Una volta disattivato Nagle, hai la maggior parte della velocità di UDP e sarai in grado di creare un gioco di reazione a contrazione . In effetti, ho creato un gioco del genere usando TCP in Flash:

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

Spero che aiuti!


App non operativa al suo collegamento, signore.
Ingegnere,

Link completamente ruotato, signore. Ottengo un test del server Apache.
Gustavo Maciel il

4

Per i giochi FPS utilizziamo sempre UDP. Soprattutto se stai facendo uno sparatutto a contrazione dove i ping contano.


4

Dipende dal tipo di gioco.

Alcuni giochi come RTS, giocano molto meglio su TCP e in genere usano TCP tutto il tempo.

Il vero problema con TCP è che se si ottiene la perdita di pacchetti - anche una piccola quantità - la connessione "si blocca" fino a quando non si verifica la ritrasmissione. Il sistema operativo non è in grado di fornire dati non ordinati all'applicazione (questo rompe le garanzie di TCP, ma anche TCP non mostra i limiti del frame dell'applicazione). Lo stallo della connessione significa che successivamente arrivano i dati in ritardo. Ma in un gioco (ad esempio) FPS, i dati non aggiornati sono inutili.

Con UDP, l'applicazione può scegliere cosa fare con i dati in ritardo o fuori servizio. Può (e per un gioco come FPS, di solito) ignorare i vecchi dati e prendere solo quelli più recenti. Un pacchetto perso occasionale non ritarda affatto i pacchetti successivi. Se alla fine arriva un pacchetto ritardato, può essere ignorato dal gioco.


Si noti che l'implementazione dovrà gestire l'aspetto dello scarto dei pacchetti in ritardo, poiché UDP lo tratterà come un datagramma ricevuto.
Guvante,

3

Non accettare semplicemente una risposta positiva "sì o no, perché ho detto così", in quanto potresti aprirti a dover combattere un sacco di problemi con UDP che in realtà non devi affrontare.

Nessuna delle altre risposte qui afferma il modo ovvio per dimostrarlo.

Prendi alcuni fatti semplici

  • Un'intestazione IP è di 20 byte, indipendentemente dal protocollo utilizzato.
  • Le intestazioni UDP sono 4 byte
  • Le intestazioni TCP sono 20 byte

Quindi ogni volta che invii un messaggio di 1 byte lungo la linea hai effettivamente inviato 25 o 41 byte a seconda del protocollo supponendo che sia necessaria anche un'intestazione IP.

fonti:

Il mio consiglio

Prendi la tua situazione in cui hai bisogno dell'interazione con il server client, stima il numero di client, quindi fai i calcoli in base ai dati che effettivamente invii tra i 2.

Un esempio

Diciamo che invio 10 messaggi da 1 byte ciascuno per aggiornamento nel mio gioco e sto aggiornando circa 60 fps, quindi ho bisogno di inviare 60 * 10 = 600 byte al secondo dei dati dei messaggi effettivi + le intestazioni pertinenti.

Ora, a seconda del gioco, potrei inviarlo tutto come un singolo messaggio, quindi il mio overhead dal livello TCP è di soli 40 byte (in realtà un costo su UDP di 20 byte al secondo), non avere quel sovraccarico è un costo potenziale di 600 byte ( perché potrebbe essere necessario inviare nuovamente l'intero flusso di messaggi).

Se tuttavia è di vitale importanza che ogni messaggio sia inviato da solo nell'istante in cui è pronto per essere inviato, ho 600 messaggi (anche 600 byte) + 40 * 600 = 24k di overhead TCP o ~ 14k di overhead UDP al secondo + 600 byte di dati dei messaggi.

Ancora una volta, poniamo le domande: quanto sono vitali quei messaggi, quanto sono frequenti e possono essere raggruppati in qualche modo per ridurre le spese generali?

Questo è basato solo su un mucchio di messaggi a byte singolo, in genere si farebbe qualcosa di molto diverso, ma senza sapere che i dati grezzi inviati sono difficili da dimostrare in entrambi i casi se TCP si adatta meglio alla propria situazione rispetto a UDP.

Quindi funzionerà?

Bene, se hai un tipico fps e la posizione è importante (per evitare imbrogli o decisioni errate), devi sapere che il tuo flusso di rete è realizzabile, ma 32 giocatori ciascuno streaming che 24k + byte di messaggi avanti e indietro (quindi 768KB / s + messaggi) ... si tratta di una linea a banda larga da 10 MB / s solo per singole intestazioni basata sull'invio di almeno 1 messaggio per frame da ciascun client a tutti gli altri client tramite un server.

Ovviamente non codificherai il funzionamento del tuo server e client in quel modo e le dimensioni dei messaggi sono molto probabilmente molto più grandi e probabilmente un po 'meno frequenti di 1 byte per frame nella maggior parte delle situazioni, quindi è difficile dirlo senza vedere un mondo reale "questo è il dato che devo inviare" esempio.

Il mio caso

Nel mio caso ho fatto appello al fatto che si tratta di un ragionevole sovraccarico, ma si basa sul modo in cui costruisco i miei flussi di messaggi in modo da non avere enormi costi generali rispetto ad alcuni progetti.

TCP funziona bene e ho un server MMO scalabile e un framework client ma non ho bisogno di trasmettere molti dati in frame o molti piccoli pacchetti perché posso raggruppare le mie chiamate.

per altri: TCP semplicemente non lo farà, e possono solo usare UDP ma devono accettare che non darà loro garanzie su ciò che ottengono (ordine / garanzia di arrivo).

Altre considerazioni

Molti motori di gioco scarsamente codificati gestiscono tutto sul thread principale della cpu, quindi alla cpu viene spesso concesso solo un tempo molto piccolo per gestire il codice di rete, un'implementazione decente sia del servizio che del client sarebbe completamente asincrona e possibilmente spingere e estrarre i messaggi in batch.

Ci sono alcune buone librerie di rete là fuori, ma come visto qui, molti sembrano avere un'opinione che UDP è "semplicemente migliore", bene fattore prima delle tue esigenze e che potrebbe non essere il caso, e trovare una biblioteca che non lo fa un fattore che può comportare una configurazione TCP scarsamente codificata rispetto alla variante UDP nella stessa libreria (sto solo dicendo di averlo visto e i test di carico lo hanno dimostrato).

Costruisci prima qualcosa una base tecnica dei dati che desideri inviare e testalo, quindi fai i calcoli per ridimensionarlo, nel caso peggiore testalo distribuendolo su un cloud e fai in modo che 50 computer eseguano un client di prova per vedere se è in grado di gestirlo il tuo limite di 32 giocatori per partita (o qualsiasi limite tu possa avere).


2

Non credo ... I giochi in cui il trasferimento dei dati è molto frequente (al passaggio del mouse o verso il basso), dovrebbero usare UDP. Ritarderà anche su LAN se si utilizza TCP.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.