Sunucu tarafı `TIME_WAIT` gerçekten nasıl çalışır?


11

Bu konuda birkaç SE sorusu olduğunu biliyorum ve bu noktaya gelmeden önce önemli olanların çoğunu okuduğuma inanıyorum.

"Sunucu tarafı TIME_WAIT" ile, sunucu tarafında close () başlatılan sunucu tarafı soket çiftinin durumunu kastediyorum.

Sık sık bana aykırı gelen bu ifadeleri görüyorum:

  1. Sunucu tarafı TIME_WAITzararsızdır
  2. Ağ uygulamalarınızı, istemcilerin yakın başlatması için tasarlamanız gerekir (), bu nedenle TIME_WAIT

Bu çelişkili bulmamın nedeni TIME_WAIT, istemcide bir sorun olabileceğidir - istemci kullanılabilir bağlantı noktalarından kaçabilir, bu nedenle özünde yukarıdaki, yükün TIME_WAITsorun olabileceği istemci tarafına taşınmasını tavsiye eder . sorun olmayan sunucu tarafı.

İstemci tarafı TIME_WAITelbette sadece sınırlı sayıda kullanım durumu için bir sorundur. İstemci-sunucu çözümlerinin çoğu bir sunucuyu ve birçok istemciyi içerir, istemciler genellikle bir sorun olması için yeterince yüksek sayıda bağlantıyla uğraşmazlar ve öyle olsalar bile, "akılcı" için bir takım öneriler vardır ( aksine SO_LINGER0 zaman aşımı ile, ya da) tcp_tw sysctl ile mücadele istemci tarafı karışma TIME_WAITçok hızlı bir şekilde çok fazla sayıda bağlantı oluşturmak kaçınarak. Ancak bu her zaman mümkün değildir, örneğin:

  • izleme sistemleri
  • yük jeneratörleri
  • vekiller

Diğer taraftan, sunucu tarafının nasıl yardımcı olduğunu bile anlamıyorum TIME_WAIT. Bunun nedeni TIME_WAITbile orada, TCPartık ait olmadıkları akışlara eski parçaların enjekte edilmesini engellemesidir . İstemci tarafı TIME_WAITiçin ip:port, bu eski bağlantının sahip olabileceği aynı çiftlerle bir bağlantı oluşturmayı imkansız hale getirerek gerçekleştirilir (kullanılan çiftler tarafından kilitlenir TIME_WAIT). Ancak sunucu tarafı için, yerel adres kabul edilen bağlantı noktasına sahip olacağından ve her zaman aynı olacağından ve sunucu (AFAIK, sadece ampirik kanıtım var) bağlantıyı reddedeceği için bu önlenemez çünkü gelen eş, yuva tablosunda zaten var olan adres çiftini oluşturur.

Sunucu tarafı TIME-WAIT'ın yok sayıldığını gösteren bir program yazdım. Ayrıca, test 127.0.0.1'de yapıldığı için, çekirdeğin, sunucu tarafı mı yoksa istemci tarafı mı olduğunu bile belirten özel bir biti olmalıdır (aksi takdirde demet aynı olacaktır).

Kaynak: http://pastebin.com/5PWjkjEf , Fedora 22'de test edildi, varsayılan net yapılandırma.

$ gcc -o rtest rtest.c -lpthread
$ ./rtest 44400 s # will do server-side close
Will initiate server close
... iterates ~20 times successfully
^C
$ ss -a|grep 44400
tcp    TIME-WAIT  0      0            127.0.0.1:44400         127.0.0.1:44401   
$ ./rtest 44500 c # will do client-side close
Will initiate client close
... runs once and then
connecting...
connect: Cannot assign requested address

Bu nedenle, sunucu tarafı için TIME_WAIT, aynı bağlantı noktası çiftindeki bağlantılar hemen ve başarıyla yeniden kurulabilir ve istemci tarafı TIME-WAITiçin ikinci yinelemede connect()haklı olarak başarısız olabilir

Özetlemek gerekirse, soru iki katlıdır:

  • Sunucu tarafı TIME_WAITgerçekten hiçbir şey yapmıyor mu ve bu şekilde bırakılıyor RFCmu?
  • Öneri, sunucunun TIME_WAITyararsız olduğu için istemcinin close () başlatması mıdır?

Yalnızca 1 istemciyi havalandırmazsanız bağlantı noktalarınız tükenmez. Her istemci / sunucu IP kombinasyonu için 65535 bağlantı noktasına sahipsiniz. 1.2.3.4:1111'den bağlantı 4.3.2.1:1111'den farklıdır. Her bağlantı için sadece birkaç bayt bellek gerekir TIME_WAIT.
Marki555

Yanıtlar:


1

Burada TCP terimleri sunucu tarafında soket LISTEN durumunda olan ana bilgisayar anlamına gelir.

RFC1122 , TIME-WAIT durumundaki soketin bazı koşullarla yeni bağlantı kabul etmesine izin verir

        When a connection is closed actively, it MUST linger in
        TIME-WAIT state for a time 2xMSL (Maximum Segment Lifetime).
        However, it MAY accept a new SYN from the remote TCP to
        reopen the connection directly from TIME-WAIT state, if it:

Koşullarla ilgili kesin ayrıntılar için lütfen RFC1122'ye bakın . Ben de soket (LISTEN durumunda soket) eşleşen bir pasif AÇIK olması beklenir.

Etkin OPEN (istemci tarafı bağlantı çağrısı) böyle bir istisna içermez ve soket RFC793'e göre TIME-WAIT konumundayken hata vermelidir .

Yakın başlatma başlatılan istemci (TCP açısından ana OPEN yani bağlanma yapan ana bilgisayar) önerisi için tahminim, sizinkiyle çok benzer, bu durumda TIME-WAIT soketlerini kaynakların bol olduğu daha fazla ana bilgisayara yayıyor soketleri. Yaygın olarak, istemciler sunucuda TIME-WAIT yuvalarını yeniden kullanacak SYN göndermez. Böyle bir tavsiyenin uygulanmasının yine de kullanım durumuna bağlı olduğunu kabul ediyorum.


0

Bu muhtemelen TIME-WAIT'in gerçekte ne yaptığının ve daha da önemlisi neden önemli olduğunun en açık örneğidir. Ayrıca, TIME-WAIT'leri 'azaltmak' için Linux makinelerinde bazı 'uzman' ipuçlarından kaçınmanın nedenini açıklıyor.


Bir istemci-> sunucu bağlantısı başlatıldığında ne olacağını hala açıklamıyor ve bir sunucu bu çifti TIME_WAIT'de kilitli
tutuyor

Lütfen stackoverflow.com/questions/1490196/… adresine bakın - Cevap aradığınız şey.
Khushil

0

Bir tcp oturumu, tupple (sourceIP, sourcePort, destIP, destPort) tarafından tanımlanır. Bu nedenle, TIME_WAIT her tcp bağlantısında çalışır.

Kapanma tarafı ile ilgili olarak, bazı senaryolarda, istemci tarafından kapamak sunucudaki TIME_WAIT soketlerini azaltarak hafızayı biraz azaltabilir. Soket alanının tükenebileceği durumlarda (geçici bağlantı noktası tükenmesi nedeniyle) (örneğin, aynı sunucuya birçok bağlantısı olan açgözlü istemciler), bu sorunun her iki tarafta da çözülmesi gerekir.


Lütfen açıkla; sunucu tarafı TW'nin bir şey yapıp yapmadığını sorduğunuzda, TW bağlantısında aynı bağlantının tekrar kullanılıp kullanılamayacağını merak edersiniz. Yanıt hayırdır, çünkü tupple tarafından tanımlanan bağlantı sunucunun tcp tablosunda yer alır. İstemci yakında aynı bağlantıyı açmaya çalışırsa, bir RST alır ve etkin bir şekilde tcp bağlantısını reddeder. Bu arada, Khushil'in makalesi çok açıklayıcı.
basos

Çok üzgünüm, cevabınız aslında soruyu cevaplıyor, yanlış okudum ve yorumumu geri çektim. Ancak, sunucu tarafında hiçbir koruma olduğunu kanıtlamak gibi görünüyor kodu var gibi, yanlış gibi görünüyor TIME_WAIT(Ben bu bilgi ile soru güncelledi). @ Khushil'in referansı sunucu tarafındaki TIME_WAITvakaları yeterince ayrıntılı olarak kapsamaz .
Pawel Veselov

-2

Güvenilir olmayan bir protokolle, eş cihazınızdan son mesajı aldığınızdan asla emin olamazsınız, bu nedenle eşinizin telefonu aniden kapattığını varsaymak tehlikelidir. TCP protokolünün büyük bir dezavantajı, sadece 65000 kadar bağlantı noktasının aynı anda açılabilmesidir. Ancak bunun üstesinden gelmenin yolu, bağlantı noktası numaralarını hızlı bir şekilde geri dönüştürmekten ziyade yükle daha iyi ölçeklenen bir sunucu çiftliğine geçmek olacaktır. İstemci sonunda, temel bir iş istasyonu ise bağlantı noktalarının bitmesi pek olası değildir.


Çok üzgünüm, ama bu sorumu cevaplamıyor.
Pawel Veselov
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.