TCP protokolü gerçek zamanlı çok oyunculu oyunlar için yeterli mi?


57

Günün sonunda çevirmeli / ISDN / yavaş geniş bant üzerinden TCP bağlantısı kesik, zorlu oyunlarla sonuçlandı, çünkü tek bir bırakılan paket yeniden eşleşmeyle sonuçlandı. Bu, birçok oyun geliştiricisinin, kendi güvenilirlik katmanlarını UDP'nin üstüne uygulamak zorunda kalmaları veya sıra dışı bırakılabilecek veya alınamayan iletiler için UDP'yi kullanmaları ve güvenilir olması gereken bilgiler için paralel bir TCP bağlantısı kullanmaları anlamına geliyordu.

Ortalama bir kullanıcının şimdi daha hızlı ağ bağlantıları olduğu göz önüne alındığında, FPS gibi gerçek zamanlı bir oyun bir TCP bağlantısı üzerinden iyi performans verebilir mi?


Yanıtlar:


36

Hayır derdim. Oyun nesnelerinin geniş bilgisinin olabildiğince hızlı olması gerekir ve bunun için UDP kullanmak daha iyidir, çünkü güvenilirlik% 100 müşfik değildir. Modern bağlantılarda bile UDP, enterpolasyon ve bunun gibi bazı özel düşünceler yapmanız gerekecek kadar yavaş. Sadece aktarılan veri miktarı açısından bile, TCP buna çok ek yük katacaktır.

Bununla birlikte, TCP çok oyunculu müzakere, sohbet mesajları, puan güncellemeleri vb. Gerçek zamanlı olmayan şeyler için mükemmel şekilde kabul edilebilir.


7
Sean hemen hemen parada. Eğer tesadüfen, C # /. NET'te bir oyun geliştiriyorsanız (biliyorsunuz!), Lidgren Ağ Kütüphanesi'ni ( code.google.com/p/lidgren-library-network ) oldukça hoş buldum. iyi seçim. İhtiyacınız olursa UDP üzerinden düzenli ve güvenilir mesajlaşma bile sağlar.
Mike Strobel,

2
Hem TCP hem de UDP'yi karıştırmak akıllıca değil; TCP'nin akış kontrolünü gerçekleştirmesinin bir sonucu olarak, paket kaybına neden olabilir. (kaynak: isoc.org/INET97/proceedings/F3/F3_1.HTM )
Jason Kozak

4
Ayrıca, bazı durumlarda, son kullanıcılarınızın UDP trafiğini engelleyen ISS'lerin arkasında oturacaklarını, UDP trafiğini önleyen yönlendirici ayarlarına sahip olacaklarını veya aksi takdirde UDP kullanmanın idealden daha az olduğu bir durumda olduğunu akılda tutmak önemlidir. Bu durumlarda, oyununuz destekliyorsa, TCP iletişimine geri dönebilmek oldukça kullanışlıdır.
Charles Ellis,

UD için bir başka + nokta, doğal olarak paketlenmiş olması, gerekirse TCP'de taklit etmeniz gerektiğidir (boilderplatecode), ne yazık ki daha modern protokoller pencereler tarafından desteklenmiyor (bu berbat)
Quonux

11

Flash, UDP'yi desteklemediğinden, çok oyunculu Flash oyunlarına bakarak, TCP / IP ile nelerin mümkün olup olmadığı hakkında neyin iyi olduğu hakkında bir fikir edinebilirsiniz. Temel olarak, yıldırım hızında tepki sürelerine dayanmadıkça gerçek zamanlı oyunlar oluşturabilirsiniz. Birkaç örnek:

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

http://everybodyedits.com/

UDP kullanma seçeneğiniz varsa, gerçekten yapmalısınız, ancak Flash ile ne yazık ki bu seçeneği alamadınız.


8

Değişir.

World of Warcraft gibi oyunlar iletişimleri için TCP kullanıyor, çünkü onu kullanarak birçok sorunu çözüyorsunuz. Sonuç olarak daha yüksek bir ping olabilir, ancak birçok oyun için bu kabul edilebilir. Protokolünüz olarak UDP kullanıyor olsanız bile, uzamsal enterpolasyon yapmanız gerekir.


1
Bu sadece ping değil. WoW'da oyuncu-oyuncu çarpışmasının olmamasının bir nedeni var. İyi yapmak çok zor olurdu. WoW TCP kullanabilir, çünkü nerede durduğunuz çok önemli değil. Hedefleme ve saldırı, canavarın veya düşman oyuncunun gerçek pozisyonuna bağlı değildir. Bu şeyleri önemsiyorsanız, TCP oyun deneyimine zarar verir.
Nuoji,

6

Müşteri / sunucu mimariniz temizse, taşıma katmanı (neredeyse) farketmez.

TCP'nin bazı dezavantajları vardır, ancak bunlar kolayca iptal edilir.

Yani evet, TCP ve bir beyin tek ihtiyacınız.

Yaygın ağ kurulumları (proxy'ler, güvenlik duvarları, vb.) İle bugün UDP, yerel (okuma: LAN) oyunlar hariç herkes için oldukça yararsızdır.


7
Oy vermediyseniz, lütfen neden bir yorum bırakın. TCP kullanıyoruz ve onunla hiçbir zaman tek bir sorunumuz olmadı.
Andreas,

3
Buradaki ortak ağ kurulumlarının alaka düzeyini göremiyorum. Güvenlik duvarları genellikle yalnızca barındırma sunucularına müdahale eder, ancak protokolden bağımsız olarak bile olsa proxy'ler gecikmiş veya düşmüş paket riskini artırır ve bu da UDP'yi yerel bir ağa göre çok daha faydalı kılar. UDP'nin sakıncaları, bütünlük kontrolleri yaparak büyük ölçüde üstesinden gelinebilir, ancak daha hızlı hale getirmek için TCP'den özellik alamazsınız.
Marcks Thomas

1
Nagles'tan bahsetmelisin . TCP'nin kötü olmasının temel sebebinin her zaman olduğunu unutuyorum (Nagle'ın istemcide / sunucuda arabellek paketleri, temelde onları oyununuzdan alıkoyması ve ek gecikme getirmesi).
bobobobo

Gecikme söz konusuysa, TCP yerine UDP kullanmanızın birkaç nedeni vardır. Gecikme umursamıyorsanız ve / veya yeterli müşteri tarafı tahmininde bulunabiliyorsanız, TCP yeterli olabilir. Gerçek zamanlı oyunlar durumunda. TCP'yi unut.
Nuoji,

6

Nagle algoritmasını kapatırsanız UDP yerine TCP kullanmak tamamen kabul edilebilir .

Nagle'ı kapattığınızda, UDP'nin hızının çoğuna sahip olursunuz ve bir seğirme reaksiyonu oyunu oluşturabilirsiniz . Aslında, Flash'ta TCP kullanarak böyle bir oyun yaptım:

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

Umarım yardımcı olur!


Bağlantınızda olmayan operasyonel uygulama, efendim.
Mühendis

Bağlantı tamamen yuvarlandı efendim. Bir Apache sunucu testi alıyorum.
Gustavo Maciel

4

FPS oyunları için her zaman UDP kullanırız. Özellikle, ping'lerin önemli olduğu bir seğirme atıcı yapıyorsanız.


4

Oyunun türüne bağlı.

RTS gibi bazı oyunlar TCP üzerinden çok daha iyi oynar ve genellikle her zaman TCP kullanır.

TCP ile ilgili asıl sorun, paket kaybı - küçük bir miktar bile olsa - yeniden bağlantı gerçekleşene kadar bağlantının "durması" olmasıdır. İşletim sistemi uygulamaya sıra dışı veri gönderemez (bu, TCP'nin garantilerini ihlal eder, ancak TCP de uygulama çerçevesi sınırlarını göstermez). Bağlantı duraklaması, geç verinin daha sonra geldiği anlamına gelir. Ancak bir (örneğin) FPS oyununda, güncel olmayan veriler işe yaramaz.

UDP ile, uygulama geç veya sıra dışı verilerle ne yapılacağını seçer. Bu (ve FPS gibi bir oyun için genellikle yapar) eski verileri görmezden gelir ve sadece sonuncusunu alır. Arada sırada kaybolan bir paket, sonraki paketleri hiç geciktirmez. Gecikmeli bir paket sonunda gelirse, oyun tarafından göz ardı edilebilir.


UDP, alınan bir datagram olarak göreceğinden, uygulamanızın gecikmiş paketleri atma yönünü ele alması gerektiğini unutmayın.
Guvante

3

Sadece "evet ya da hayır demiştim ya da hayır demiştim" deyince, UDP ile yüzleşmek zorunda kalmayacağınız bir sürü sorunla mücadele etmek için kendinizi açıyor olabilirsiniz.

Buradaki diğer cevapların hiçbiri, bunu kanıtlamanın açık yolunu belirtmiyor.

Bazı basit gerçekleri al

  • Bir IP başlığı, hangi protokolü kullanırsanız kullanın, 20 bayttır.
  • UDP başlıkları 4 bayttır
  • TCP başlıkları 20 bayttır

Dolayısıyla, her satır için 1 baytlık bir mesaj gönderdiğinizde, bir IP başlığının da gerekli olduğunu varsayan protokole bağlı olarak aslında 25 veya 41 bayt gönderdiniz.

kaynaklar:

Benim tavsiyem

Durumunuzu istemci-sunucu etkileşimine ihtiyacınız olan yerde alın, müşteri sayısını tahmin edin, sonra ikisi arasında gönderdiğiniz verilere göre hesaplamayı yapın.

Bir örnek

Oyunumda güncelleme başına her biri 1 bayt olan 10 mesaj gönderdiğimi ve yaklaşık 60 fps güncellediğimi varsayalım, böylece gerçek mesaj verisinin saniyesinde 60 * 10 = 600 bayt + ilgili başlıkları göndermem gerekiyor.

Şimdi oyuna bağlı olarak, hepsini tek bir mesaj olarak gönderebildiğim için TCP katmanından ek yüküm sadece 40 bayttır (etkin saniyede 20 bayt UDP maliyeti), bu ek yüke sahip olmamak, potansiyel olarak 600 bayt maliyettir ( çünkü tüm ileti akışını tekrar göndermem gerekebilir).

Bununla birlikte, her mesajın gönderilmeye hazır olduğu anda kendi başına gönderilmesi hayati önem taşıyorsa, 600 mesajım var (ayrıca 600 bayt) + 40 * 600 = 24k değerinde TCP ek yükü veya saniyede ~ 14k UDP ek yükü + 600 bayt mesaj verisi.

Yine, şu soruları soruyoruz, bu mesajların ne kadar hayati olduğu, ne sıklıkta oldukları ve genel giderlerin azaltılması için bir şekilde bir araya getirilebilirler mi?

Bu sadece bir sürü bayt mesajına dayanıyor, tipik olarak çok farklı bir şeyler yaparsınız, ancak ham verinin TCP'nin UDP'den daha iyi bir durumda olup olmadığını ispatlamak zor olduğunu bilmeden.

Yani işe yarayacak mı?

Tipik bir fps'niz varsa ve konum önemliyse (aldatma veya yanlış kararları önlemek için), ağ akışınızın uyumlu olduğunu bilmeniz gerekir, ancak her biri 24k + iletinin akıp gittiği 32 oynatıcı (yani 768KB / s + mesajlar) ... bu, her bir istemciden bir sunucu aracılığıyla diğer tüm istemcilere her kare için en az 1 mesaj göndermeye dayanan ayrı başlıklar için bir 10mb / s genişbant hattı ile ilgilidir.

Açıkçası sunucunuzu ve istemcinizi bu şekilde çalışacak şekilde kodlamayacaksınız ve mesaj boyutlarının çoğu durumda daha büyük ve muhtemelen kare başına 1 bayttan biraz daha az olması muhtemeldir, bu nedenle gerçek bir dünya görmeden söylemek zor "bu, göndermem gereken veriler" örneği.

Benim olayım

Durumumu makul bir yükü olarak yaptım, ancak bu, mesaj akışlarımı nasıl oluşturduğuma dayanıyor, bu yüzden bazı tasarımlara kıyasla çok fazla genel masrafa sahip değilim.

TCP iyi çalışıyor ve ölçeklenebilir bir MMO sunucusu ve istemci çerçevem ​​var, ancak çağrılarımı toplayabildiğim için çok fazla veriyi çerçeve veya çok sayıda küçük paket akışına göndermem gerekmiyor.

diğerleri için: TCP sadece yapmayacak ve sadece UDP'yi kullanabilirler ancak ne aldıklarına dair kendilerine güvence vermeyeceklerini kabul etmek zorundadırlar (sipariş / varış garantisi).

Diğer hususlar

Birçok kötü kodlanmış oyun motoru, işlemci üzerindeki ana iş parçacığındaki her şeyi kullanır, böylece CPU'ya genellikle ağ kodunu işlemek için çok az zaman verilir, hem hizmet hem de müşterinin düzgün bir şekilde uygulanması tamamen asenkron ve muhtemelen zorlanır ve mesajları gruplar halinde çekin.

Dışarıda bazı iyi ağ kütüphaneleri var ama burada görüldüğü gibi, birçoğunun UDP'nin "sadece daha iyi" olduğu, ilk önce kendi ihtiyaçlarınızda iyi bir faktör olduğu ve durum böyle olmadığı ve olmayan bir kütüphane bulduğu görüşünde olduğu görülüyor. Yaptığınız şeydeki faktör, aynı lib'deki UDP varyantına kıyasla kötü kodlanmış bir TCP kurulumuna neden olabilir (sadece bunu gördüm ve yükleme testleri bunu kanıtladı).

Öncelikle göndermek istediğiniz verinin teknik temelini oluşturun ve test edin, sonra ölçeklendirmek için matematik yapın, en kötü durum yükü bir buluta dağıtarak test edin ve 50 bilgisayarın test edip edemeyeceğini görmek için bir test istemcisi çalıştırmasını sağlayın Oyun başına 32 oyuncu limitiniz (veya sahip olabileceğiniz herhangi bir limit).


2

Sanmıyorum ki ... Veri aktarımının çok sık olduğu oyunlar (fare ile ya da key-down'de) UDP kullanmalı. TCP kullanılıyorsa, LAN bile gecikecek.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.