19 puan yazan GN⁺ 2025-11-16 | 1 yorum | WhatsApp'ta paylaş
  • TCP (Transmission Control Protocol), kararsız ağ ortamlarında bile güvenilir ve sıralaması garanti edilen veri iletimini mümkün kılan internetin temel protokolüdür
  • IP yalnızca ana makineler arasında veri iletiminden sorumluyken, TCP port tabanlı süreçler arası iletişimi ve hata kurtarma, yeniden iletim, sıra kontrolünü gerçekleştirir
  • Akış kontrolü (flow control) ve tıkanıklık kontrolü (congestion control) ile alıcı tamponunun ya da ağ bant genişliğinin sınırlarının aşılmaması için ayarlama yapar
  • C diliyle yazılmış basit TCP sunucusu ve HTTP sunucusu örnekleri üzerinden soket oluşturma, bind, listen, bağlantı kabul etme, gönderme ve alma süreçleri somut biçimde açıklanır
  • TCP’nin sıra numarası, ACK numarası, pencere, sağlama toplamı, bayraklar (SYN/ACK/FIN/RST) gibi iç yapısı, günümüz internetinin kararlı çalışmasını mümkün kılan temel altyapıdır

TCP'nin gerekliliği ve rolü

  • IP yalnızca ana makineler arasında paket iletiminden sorumludur; süreçler arası iletişim için TCP/UDP gibi bir taşıma katmanı gerekir
    • IP adresi “bina”, port ise “daire” benzetmesiyle açıklanır; her uygulama bir porta bind edilerek iletişim kurar
  • TCP, paket kaybı, çoğaltma, sıra bozulması gibi ağ kararsızlıklarını gizler ve yeniden iletim, sağlama toplamı gibi mekanizmalarla güvenilirliği garanti eder
  • Router'lar basit tutulur, güvenilirlik ise iletişimin iki ucunda ele alınır; böylece ağ altyapısının karmaşıklığı azaltılır
  • Bu yapı sayesinde HTTP, SMTP, SSH gibi başlıca internet servisleri kararlı şekilde çalışır

Akış kontrolü ve tıkanıklık kontrolü

  • Alıcı taraf, veriyi geçici olarak depolamak için çekirdeğin alım tamponunu (receive buffer) kullanır; tampon boyutu net.ipv4.tcp_rmem ile ayarlanır
  • Gönderici taraf, alıcının izin verdiği veri miktarını pencere (window) alanı üzerinden alır ve gönderim miktarını buna göre ayarlar
  • Ağ genelindeki bant genişliği farklarından doğan tıkanıklığı (congestion) önlemek için TCP, tıkanıklık kontrol algoritmaları uygular
    • 1986'da yaşanan tıkanıklık çökmesi (congestion collapse) sonrasında “back-off” mekanizması eklendi

TCP sunucusu ve HTTP sunucusu örnekleri

  • C diliyle yazılmış temel bir TCP echo sunucusu, istemciden gelen girdiyi alıp başına “you sent:” ekleyerek yeniden gönderir
    • socket(), bind(), listen(), accept(), send(), recv() gibi Berkeley sockets API kullanılır
    • Sunucu sleep() durumundayken istemcinin verisi alım tamponunda bekler ve daha sonra sırayla işlenir
  • Basit bir HTTP/1.1 sunucusu örneğinde, TCP bağlantısı üzerinden istek kabul edilir ve HTTP/1.1 200 OK başlığı ile gövde gönderilir
    • İstek sayısı i ile sayılır; curl localhost:8080 isteğinde “[1] Yo, I am a legit web server” biçiminde yanıt döner

TCP segment yapısı ve temel alanlar

  • TCP segmenti kaynak/hedef port, sıra numarası, ACK numarası, pencere boyutu, sağlama toplamı, bayraklar gibi alanlardan oluşur
    • Portlar 16 bit olarak ayrılır; bu sayede en fazla 64K port kullanılabilir
    • Bir bağlantı, (protocol, source IP, source port, destination IP, destination port) biçimindeki 5-tuple ile tanımlanır
  • Sıra numarası, iletilen bayt aralığını; ACK numarası ise alınması tamamlanan baytları gösterir
    • Eksik veri varsa ACK o noktada durur, yeniden iletimden sonra kümülatif ACK ile güncellenir
  • Bayrak bitleri bağlantı durumunu kontrol eder
    • SYN/ACK, 3 aşamalı el sıkışma ile bağlantıyı kurar
    • FIN, 4 aşamalı el sıkışma ile bağlantıyı sonlandırır
    • RST, anormal kapanma ya da hata durumunda bağlantıyı hemen keser
  • Pencere alanı, alınabilecek veri miktarını gösterir; ss komutuyla tampon durumu (rb131072, tb16384) kontrol edilebilir
  • Sağlama toplamı (checksum), segment içindeki 16 bitlik toplama ile hata tespiti yapar

Sonuç

  • TCP, güvenilirlik, sıra ve bütünlüğü garanti eder; kararsız internet ortamlarında bile uygulamaların düzgün çalışmasını sağlar
  • On yıllar önce birkaç KB veri aktarmak bile zorken, bugün 4K streaming sıradan hale gelmiştir
  • Bunu mümkün kılan TCP tasarımı ve uygulamasının inceliği, internetin sürekli büyümesinin temelidir

1 yorum

 
GN⁺ 2025-11-16
Hacker News yorumları
  • Güvenilmez bir datagram katmanı üzerinde güvenilir bir veri akışı oluşturmaya çalışırsanız, sonuçta ortaya TCP’ye çok yakın bir yapı çıkar.
    TCP’nin ilk dönem sınırlamaları küçük pencere boyutu, kayıp paketlerin yetersiz ele alınması ve yalnızca tek bir akışı yönetmesiydi.
    Bu sorunları çözmek için SCTP ve QUIC ortaya çıktı.
    Tıkanıklık kontrolü algoritmaları protokolün bir parçası değil, her bağlantının iki ucunda çalışan koddur.
    İlk algoritmalar (Reno, Vegas vb.) basitti ama yeterince etkiliydi; daha sonra büyük tamponlar, uzun RTT ve adalet gibi konuları ele alan araştırmalar sürdü.

    • Web geliştiricilerinin çoklu akışları iyi kullanamamasında da payı olduğunu düşünüyorum.
      Eskiden JavaScript ile, tek bir akış üzerinde birden çok indirmeyi önceliklendirme ve iptal özellikleriyle kontrol edebilen bir kütüphane yapmıştım.
      Bir GreaseMonkey betiğiyle bir flört sitesindeki küçük görselleri arka planda önceden getiriyor, kaydırma konumuna göre önceden yüklüyordum.
      Sonuç olarak sunucu yükünü azaltırken kullanıcı deneyimini iyileştirdim.
      İşin komiği, o betiği bir eşleşmemle paylaşmıştım ve hâlâ birlikteyiz — adeta Tinder öncesi bir Tinder gibiydi.
    • TCP oluşturulduğunda telefon şebekesi merkezli devre anahtarlama (circuit switching) düşüncesi hâkimdi.
      TCP, paket anahtarlamalı bir ağ üzerinde sanal devre sunan bir yapıydı; güvenilirliğin yeniden iletim ile sağlanması fikri ise Fransa’daki Cylades ağından geliyordu.
    • TCP’nin temel kusurlarından biri güvenliğinin sağlanamamasıdır.
      Saldırgan ağın herhangi bir yerinden veriyi enjekte edebilir (inject) ya da RST paketi ile bağlantıyı koparabilir.
      RST’yi güvenlik duvarıyla engellemek kararlılığı artırır, ancak sahte sıra numaralarıyla yapılan senkron dışı bırakma saldırıları yine de mümkündür.
      Bu yüzden tüm uygulamaların ayrı bir bağlantı üzerinden resume özelliğini uygulaması gerekir ve TCP’nin slow start sorununu da birlikte taşırlar.
      Ayrıca adres ile portu ayrıştıran kavramın kendisinin de verimsiz olduğunu düşünüyorum.
    • Bazı uygulamalar tek bir TCP bağlantısıyla da gayet iyi çalışır.
      Örneğin DNS over TLS (DoT) içinde tek bir TCP bağlantısı üzerinden birden fazla sorgu aynı anda gönderilebilir ve yanıtlar sıra bağımsız alınabilir.
      Bu, birden fazla bağlantı açmaktan daha verimli ve daha nazik bir yöntemdir.
      QUIC’in daha hızlı olup olmadığını bilmiyorum ama sunucu desteği hâlâ sınırlı.
      HTTP/1.1 pipelining ile de benzer şeyler yapılır, ancak yanıtlar sıralı gelir.
    • TCP’nin tıkanıklık kontrolü algoritmalarının protokolün dışında olması o dönem için oldukça yenilikçiydi.
      Ancak birçok üniversite dersinde bunun altı çizilmediği için, TCP’nin tek bir algoritması varmış gibi yanlış anlaşılabiliyor.
  • SCTP hakkında özel bir sevginiz olup olmadığını merak ediyorum.
    SCTP, UDP’nin mesaj odaklı yapısıyla TCP’nin güvenilirliğini birleştiren; çoklu akış ve çoklu homing destekleyen bir protokoldür.
    Birden fazla bağımsız akışı paralel taşıyabildiği için bir web sayfasının metnini ve görsellerini aynı anda gönderebilir.
    Ayrıntılar için Wikipedia: Stream Control Transmission Protocol sayfasına bakabilirsiniz.

    • SCTP sorunun yalnızca yarısını çözüyor ve birkaç yeni kusur ekliyor.
      Sonuçta en iyi çözüm UDP üzerindeki bir güvenilirlik katmanı, yani QUIC.
    • BSD kullanmayı seven ve Erlang ile çalışan biri olarak SCTP’yi çok seviyorum.
  • Yalnızca IP ile doğrudan paket gönderip gönderemeyeceğimi merak etmiştim.
    Aradaki yönlendiricilerin TCP veya UDP olmayan paketleri reddedeceğini düşünüyordum.

    • Doğrudan IP paketleri oluşturup gönderebilirsiniz.
      IPv4 için IANA protokol numarası listesi içinden 0–255 arasında bir değer belirtmeniz yeterlidir.
      Çekirdek yönlendiriciler bu alanı incelemez, ancak NAT ya da ISP ekipmanları inceleyebilir.
      İki Linux sunucu arasında deneysel numaralarla (253, 254) bile iletişim kurulabilir.
    • ICMP’yi de unutmamak gerekir. IPv6’da daha da önemlidir.
      IPsec, GRE ve L2TP gibi protokoller de TCP/UDP değildir.
      Kurumsal ağlardaki güvenlik duvarı veya NAT ortamlarında rastgele protokoller engellenebilir.
      NAT, uçtan uca ilkesini bozdu ve sonunda insanlar her şeyi TCP veya UDP üzerine, hatta HTTP üzerine koymaya başladı.
    • NAT ya da yük dengeleyici yoksa sorun olmaz, ancak bugün bunlar yaygın olduğu için IPv6 daha iyi olabilir.
    • Yönlendiriciler 3. katman cihazlarıdır, bu yüzden TCP/UDP olup olmamasıyla ilgilenmezler.
      En fazla ECMP hash için entropinin azalması gibi bir etkisi olur.
      Sonuçta asıl mesele karşı tarafın bu protokolü anlayıp anlamadığıdır.
    • TCP ve UDP yalnızca IP yüküdür; yönlendiriciler bunları yorumlamaz.
      Port numaraları ise sadece düğüm içindeki hizmet tanımlayıcılarıdır.
  • RUDP (Plan9), TCP ile UDP arasında harika bir orta yoldu.
    Reliable User Datagram Protocol sayfasına bakın.

  • TCP varsayılan hâle geldiği için, güvenilirlik ya da sıra garantisine ihtiyaç olmayan durumlarda bile otomatik olarak kullanıldı.
    Artık HTTP/3 (QUIC tabanlı) yaygınlaştıkça durumun düzelme ihtimali var.
    Ancak QUIC çok daha karmaşık ve sunduğu güç yalnızca bazı kişiler için faydalı.
    UDP + WireGuard tarzı basit bir şifreleme katmanı daha iyi bir alternatif olabilir.

  • TCP insanlığın büyük icatlarından biri, ancak yarı bağlantılı ağların (NAT tabanlı) egemenliğini öngöremedi.

    • “NAT’ı mı kastediyorsun?” diye soruluyor.
    • 1981’e dönüp “dünya çapında adresler yerine sınırlı bir aralıktaki adresleri kullanalım ve bazı düğümleri erişilemez yapalım” denseydi,
      o dönemin mühendisleri neden bilerek böyle karmaşık bir şey yapılmak istendiğini sorardı.
      Sonuçta bugünkü asimetrik bağlantı yapısı ve istemci–sunucu ayrımı böyle bir düşünceden doğdu.
  • TCP’nin tıkanıklık kontrolü algoritmaları, geliştiricilerin çoğunun bilmediği ilginç etkilere sahiptir.
    Yeni bir bağlantıda veri gönderdiğinizde ilk aktarım yavaş olur ve hız artışı gecikme (latency) tarafından belirlenir.
    Veri merkezlerinde RTT’yi birkaç mikrosaniye azaltmak bile büyük hız artışları sağlayabilir.
    Çoğu TCP yığını hız artışını bayt yerine segment başına hesapladığı için, jumbo frame kullanmak artışı 6 kat hızlandırabilir.
    AWS bu yüzden düşük anahtarlama gecikmesi ve jumbo frame desteği için çok emek harcıyor.
    Uzmanlar bu tür ayarlamaları yapıyor, ama çoğu kişi neden 10Gbps bağlantıda 10Gbps göremediğini merak edip duruyor.

  • IP üzerinde kendi protokolünüzü oluşturmak çok kolay bir işti.
    Daha 15 yıl önce bile Python ile paketleri elle oluşturup deney yapabiliyordunuz.