Bir oyun sunucusu yazarken er ya da geç karşına çıkan ilk mimari karar, taşıma katmanı protokolüdür: TCP vs UDP oyun sunucusu için hangisi doğru tercih? Cevap, "her zaman UDP" ya da "her zaman TCP" kadar basit değil. İkisi de aynı IP ağının üzerinde çalışır ama veriyi tamamen farklı garantilerle taşır; ve bu garantiler, oyununun hissedilen tepkiselliğini doğrudan belirler. Bu yazıda iki protokolün gerçekte ne yaptığını, hangi oyun türünde hangisinin mantıklı olduğunu ve pratikte nasıl karar verdiğimi anlatıyorum.
TCP ve UDP gerçekte ne yapar?
TCP (Transmission Control Protocol) bağlantı tabanlı ve güvenilirdir. Üç yönlü el sıkışma (SYN, SYN-ACK, ACK) ile bağlantı kurar, gönderdiğin her baytın karşı tarafa sırayla ve eksiksiz ulaşmasını garanti eder. Kaybolan paketi otomatik yeniden gönderir, sıralamayı düzeltir ve ağ tıkanırsa hızını kendi azaltır.
UDP (User Datagram Protocol) bağlantısız ve "ateşle-unut" mantığındadır. Datagramı yollar, gerisine karışmaz: paket kaybolabilir, sıra bozulabilir, hatta aynı paket iki kez gelebilir. Karşılığında neredeyse hiç ek yük getirmez; el sıkışma yok, yeniden gönderme beklemesi yok.
Özetle ikisi arasındaki gerçek takas şu:
- TCP: her zaman doğru ve sıralı veri, ama gecikme dalgalanması (jitter) ve "head-of-line blocking" riski.
- UDP: minimum gecikme ve tam kontrol, ama güvenilirliği kendin yazmak zorundasın.
Oyunda gecikmeyi belirleyen şey: head-of-line blocking
UDP'nin oyunlarda neden bu kadar sevildiğini anlamak için TCP'nin en sinsi sorununu görmek gerekir. TCP sıralı teslimat garanti ettiği için, tek bir paket kaybolduğunda ondan sonra gelen tüm paketler işletim sistemi tamponunda bekler; kaybolan paket yeniden gönderilip ulaşana kadar uygulamana hiçbiri teslim edilmez. Buna head-of-line blocking denir.
Hızlı tempolu bir nişancı oyununda bu felakettir: oyuncunun 40 ms önceki pozisyonunu içeren kayıp bir paket için, çoktan eskimiş olmasına rağmen, en güncel pozisyon paketleri de bekletilir. Oysa oyun mantığında genelde en son durum önemlidir; üç kare önceki pozisyonun kaybolması umursamaz bir şeydir. UDP burada her datagramı bağımsız işlemene izin verir: eski olanı atar, en güncel olanı hemen kullanırsın.
Hangi oyun türünde hangisi?
Pratik bir karar çerçevesi şöyle kurulabilir:
- Gerçek zamanlı, hızlı tempolu (FPS, MOBA, dövüş, yarış, aksiyon MMO): UDP. Sürekli akan pozisyon/girdi güncellemeleri için düşük gecikme her şeyden önemli, tek bir paketin kaybı tolere edilebilir.
- Tur tabanlı / yavaş tempolu (kart oyunu, satranç, tarayıcı tabanlı strateji, sosyal/sohbet): TCP. Her aksiyon kritik, milisaniyeler önemsiz, basitlik ve garantili teslimat kazanır.
- Klasik MMORPG (örneğin Metin2, Tibia gibi): pratikte çoğu TCP kullanır. Envanter, ticaret, sohbet ve dünya durumu güvenilirlik ister; hareket biraz daha akıcı olsa da TCP'nin tutarlılığı bu tür için yeterlidir ve sunucu kodunu çok basitleştirir.
Önemli bir nokta: birçok modern oyun ikisini birden kullanır. Hareket ve girdi UDP üzerinden akarken, giriş kimlik doğrulama, satın alma, chat ve kalıcı durum TCP üzerinden gider. "Tek protokol seçmek zorundayım" diye düşünme.
Linux'ta basit bir karşılaştırma
İki protokolün soket seviyesinde ne kadar farklı kurulduğunu görmek, kararı somutlaştırır. Aşağıda C++ ile (POSIX soketleri) bir TCP dinleyici ile bir UDP dinleyicinin iskeleti var. Fark, SOCK_STREAM ile SOCK_DGRAM ve TCP'deki listen/accept adımlarında:
// TCP sunucu iskeleti
int fd = socket(AF_INET, SOCK_STREAM, 0);
bind(fd, (sockaddr*)&addr, sizeof(addr));
listen(fd, 128);
int client = accept(fd, nullptr, nullptr); // bağlantı kabul et
recv(client, buf, sizeof(buf), 0); // güvenilir, sıralı akış
// UDP sunucu iskeleti
int fd = socket(AF_INET, SOCK_DGRAM, 0);
bind(fd, (sockaddr*)&addr, sizeof(addr));
sockaddr_in from; socklen_t len = sizeof(from);
recvfrom(fd, buf, sizeof(buf), 0,
(sockaddr*)&from, &len); // bağlantısız datagram
UDP'de accept ve kalıcı bağlantı yok; her datagram kimden geldiğini recvfrom ile söyler. Bu yüzden "kim hangi oyuncu" eşlemesini, oturum yönetimini ve güvenilirliği uygulama katmanında kendin kurmak zorunda kalırsın.
UDP seçtiysen: güvenilirliği kendin kurarsın
UDP'nin "ücretsiz hız"ı bedava değildir; TCP'nin sana hazır verdiği işlerin bir kısmını elle yazarsın. Tipik olarak ihtiyaç duyacakların:
- Sıra numaraları: her pakete artan bir numara koyup eski/yinelenen paketleri ayıklamak.
- Seçici güvenilirlik: her şeyi değil, sadece kaybolması kabul edilemez olanları (örn. "ateş edildi", "öldü" olayları) ACK ile garantilemek.
- Tıkanıklık ve hız kontrolü: ağı boğmamak için gönderim hızını ayarlamak.
İyi haber: bunu sıfırdan yazmak zorunda değilsin. ENet, GameNetworkingSockets (Valve) veya KCP gibi olgun kütüphaneler, UDP üzerine isteğe bağlı güvenilir/sıralı kanallar ekler. Çoğu ekip için doğru yol, ham UDP yerine bu kütüphanelerden birini kullanmaktır.
Pratik bir karar listesi
- Oyun hızlı tempolu mu ve "en güncel durum" eski durumdan daha mı değerli? → UDP.
- Her mesaj kritik ve sıra şart mı, milisaniyeler önemsiz mi? → TCP.
- Geliştirme süresi kısıtlı, prototip mi yapıyorsun? → TCP ile başla, gerekirse sonra hareketi UDP'ye taşı.
- Hibrit mantıklı mı? → Evet, çoğu üretim oyunu öyle yapar.
Sık Sorulan Sorular
UDP, TCP'den her zaman daha mı hızlıdır?
Ham bağlantı hızı (bant genişliği) anlamında belirgin bir fark yoktur; ikisi de aynı ağı kullanır. UDP'nin avantajı gecikme tutarlılığı: paket kaybında bekletme yapmadığı için jitter ve head-of-line blocking yaşatmaz. Yani "daha hızlı" değil, "daha tepkisel ve öngörülebilir" demek daha doğru.
Tarayıcı tabanlı bir oyunda UDP kullanabilir miyim?
Doğrudan ham UDP'yi tarayıcıdan açamazsın. WebSocket TCP üzerinde çalışır; düşük gecikmeli UDP benzeri taşıma için WebRTC data channel (UDP üzerinde, isteğe bağlı güvenilir/sırasız modlu) kullanılır. Çoğu tarayıcı oyunu hız kritik değilse WebSocket ile gayet iyi çalışır.
Metin2 gibi bir MMORPG için TCP yeterli mi?
Evet. Bu tür oyunların orijinal mimarisi TCP üzerine kuruludur ve binlerce oyuncuyla sorunsuz çalışır. Akış o kadar yüksek frekanslı değildir ki TCP'nin sıralı teslimatı sorun olsun; üstelik ticaret, envanter ve dünya tutarlılığı için TCP'nin garantileri tam da istenen şeydir.
Sonuç: Doğru cevap oyununun ritmine bağlı; hızlı tempoda UDP, kritik ve sıralı mesajlarda TCP, çoğu üretim ortamında ise ikisinin birleşimi. Oyun sunucusu mimarinde TCP/UDP kararını, ölçeklenmeyi veya ağ katmanını birlikte netleştirelim mi? Benimle iletişime geç, projenin gereksinimlerine göre konuşalım.