Yazar | Kobayashi kodlaması
Kaynak | Kobayashi kodlaması (ID: CodingLin)
Java, C / C ++, Python ve diğer geliştirme pozisyonları için yapılan görüşmelerden bağımsız olarak, TCP bilgisinin bir zorunluluk olduğu söylenebilir.
TCP beni binlerce kez kötüye kullanırsa, yine de TCP'yi ilk aşkım olarak görüyorum.
Okulda işe alırken Xiaolin'in sık sık TCP mülakat soruları üzerinde tazelendiğini düşünüyorum. Gerçekten seviyorum ve acımasızca ...
Geçmiş tamam olmayacak, bugün bu korkuyu ortadan kaldıralım ve cesurca bir gülümsemeyle yüzleşelim!
Bu yüzden Kobayashi, TCP'nin üç yönlü el sıkışma ve dört kez dalgası hakkındaki mülakat sorularını derledi ve herkesle tartıştı.
1. Temel TCP anlayışı
2. TCP bağlantısı kurulması
3. TCP bağlantısı kesildi
4. Soket programlama
Not: Bu makale TCP akış kontrolü, tıkanıklık kontrolü, güvenilir iletim vb. Hakkında bilgi içermiyor, bunlar bir sonraki makalede bırakılacak!
TCP başlık formatına bakın
Önce TCP başlığının formatına bir göz atalım. İşaretlenen renkler, bu makaleye göre görece büyük olan alanları gösterir ve diğer alanlar detaylandırılmayacaktır.
TCP başlık biçimi
seri numarası: Bağlantı kurulduğunda, bilgisayar tarafından üretilen rastgele sayı başlangıç değeri olarak kullanılır ve alıcı ana bilgisayara SYN paketi yoluyla iletilir Veri her gönderildiğinde, "veri baytlarının" boyutu "toplanır". Ağ paketi bozukluğu sorununu çözmek için kullanılır.
Yanıt numarasını onaylayın: Bir dahaki sefere "beklenen" olarak alınan verilerin sıra numarasını ifade eder Gönderen bu onay yanıtını aldıktan sonra, bu sıra numarasının normal olarak alınmasından önceki verilerin olduğu düşünülebilir. Paket kaybı olmaması sorununu çözmek için kullanılır.
Kontrol biti:
ACK: Bu bit 1 olduğunda, "alındı" alanı geçerli hale gelir TCP, bağlantı ilk kurulduğunda SYN paketi dışında bu bitin 1 olarak ayarlanmasını şart koşar.
RST: Bu bit 1 olduğunda, bu, TCP bağlantısındaki bir anormalliğin bağlantıyı kesmeye zorlanması gerektiği anlamına gelir.
SYC: Bu bit 1 olduğunda, bir bağlantı kurmak ve "seri numarası" alanında seri numarasının başlangıç değerini ayarlamak istediğiniz anlamına gelir.
FIN: Bu bit 1 olduğunda, gelecekte gönderilecek başka veri olmayacağı ve bağlantının kesilmesinin beklendiği anlamına gelir. İletişim sona erdiğinde ve bağlantıyı kesmeyi umduğunda, iki iletişim tarafının ana bilgisayarları, 1 olarak FIN konumuyla TCP segmentini değiştirebilir.
Neden TCP protokolüne ihtiyacımız var? TCP hangi katman üzerinde çalışır?
IP katmanı "güvenilmezdir". Ağ paketlerinin teslimini, ağ paketlerinin düzenli teslimini veya ağ paketlerindeki verilerin bütünlüğünü garanti etmez.
OSI referans modeli ile TCP / IP arasındaki ilişki
Ağ veri paketlerinin güvenilirliğini garanti etmeniz gerekiyorsa, üst katman (taşıma katmanı) TCP protokolü sorumludur.
Çünkü TCP bir Taşıma katmanı nın-nin dürüst Veri aktarım hizmeti, alıcı uç tarafından alınan ağ paketinin Hasar yok, boşluk yok, yedeksiz ve sıralı .
TCP nedir?
TCP Bağlantı odaklı, güvenilir, bayt akışı tabanlı Taşıma katmanı iletişim protokolü.
Bağlantı yönelimli : Bağlanmak için "bire bir" olmalı, bir ana bilgisayarın aynı anda birden çok ana bilgisayara mesaj gönderebildiği UDP protokolü gibi olamaz, yani bire-çok mümkün değildir;
dürüst : Ağ bağlantısında ne tür bağlantı değişiklikleri olursa olsun, TCP bir mesajın alıcı uca ulaşacağını garanti edebilir;
Bayt akışı : Mesajların sınırları yoktur, bu nedenle mesajlarımız ne kadar büyük olursa olsun, onları iletebiliriz. Ve mesaj "sıralı". "Önceki" mesaj alınmadığında, sonraki baytı önce almış olsa bile, işlenmek üzere uygulama katmanına atılamaz. Mesaj otomatik olarak silinir.
TCP bağlantısı nedir?
RFC 793'ün "bağlantıyı" nasıl tanımladığına bir göz atalım:
Bağlantılar:
Yukarıda açıklanan güvenilirlik ve akış kontrol mekanizmaları, TCP'lerin her veri akışı için belirli durum bilgilerini başlatmasını ve sürdürmesini gerektirir.
Soketler, sıra numaraları ve pencere boyutlarını içeren bu bilgilerin birleşimine bağlantı adı verilir.
Basit ifadeyle, Güvenilirlik ve akış kontrolü bakımı sağlamak için kullanılan belirli durum bilgileri Soket, seri numarası ve pencere boyutu dahil olmak üzere bu bilgilerin birleşimine bağlantı adı verilir.
Dolayısıyla, bir TCP bağlantısı kurmanın, istemcinin ve sunucunun yukarıdaki üç bilgi üzerinde bir fikir birliğine varmasını gerektirdiğini bilebiliriz.
Priz : IP adresi ve bağlantı noktası numarasından oluşur
seri numarası : Arıza sorunları vb. Çözmek için kullanılır.
Pencere boyutu : Akış kontrolü için kullanılır
Bir TCP bağlantısı benzersiz olarak nasıl belirlenir?
Dörtlü TCP bir bağlantıyı benzersiz şekilde belirleyebilir. Dörtlü aşağıdakileri içerir:
kaynak adresi
Kaynak bağlantı noktası
Varış noktası
Hedef bağlantı noktası
TCP dörtlü
Kaynak adresi ve hedef adres alanları (32 bit) IP başlığındadır ve bunların rolü, IP protokolü aracılığıyla karşı ana bilgisayara mesaj göndermektir.
Kaynak bağlantı noktası ve hedef bağlantı noktası alanları (16 bit) TCP başlığındadır ve bunların işlevi, iletinin hangi işleme gönderilmesi gerektiğini TCP protokolüne söylemektir.
Bir bağlantı noktasında dinleyen bir IP sunucusu var, maksimum TCP bağlantısı sayısı nedir?
Sunucu genellikle belirli bir yerel bağlantı noktasında dinler ve istemcinin bağlantı talebini bekler.
Bu nedenle, istemci IP'si ve bağlantı noktası değişkendir ve teorik değer hesaplama formülü aşağıdaki gibidir:
IPv4 için, istemcideki maksimum IP sayısı 2'den 32'ye kadardır ve istemcideki maksimum bağlantı noktası sayısı, sunucu tarafındaki maksimum TCP bağlantısı sayısı olan 2'den 16'ya kadardır, bu sayı yaklaşık 2'den 48'e kadardır.
Elbette, sunucudaki maksimum eşzamanlı TCP bağlantısı sayısı teorik üst sınıra ulaşmaktan uzaktır.
Her şeyden önce, temelde dosya tanımlayıcı sınırıdır Soketler tüm dosyalardır, bu nedenle önce ulimit aracılığıyla dosya tanımlayıcı sayısını yapılandırmanız gerekir;
Diğeri bellek sınırlamasıdır Her TCP bağlantısı belirli bir miktarda bellek kullanır ve işletim sistemi sınırlıdır.
UDP ve TCP arasındaki fark nedir? İlgili uygulama senaryoları nelerdir?
UDP, karmaşık bir kontrol mekanizması sağlamaz, ancak "bağlantısız" bir iletişim hizmeti sağlamak için IP kullanır.
UDP protokolü gerçekten basittir, başlık yalnızca 8 bayttır (64 bit) ve UDP başlığının biçimi aşağıdaki gibidir:
UDP başlık biçimi
Hedef ve kaynak bağlantı noktaları: esas olarak mesajın hangi işleme gönderilmesi gerektiğini UDP protokolüne bildirmek için.
Paket uzunluğu: Bu alan, UDP başlığının uzunluğu ile verilerin uzunluğunun toplamını depolar.
Sağlama toplamı: Sağlama toplamı, güvenilir UDP başlığı ve verileri sağlamak için tasarlanmıştır.
TCP ve UDP arasındaki fark:
1. Bağlanın
TCP, bağlantı yönelimli bir taşıma katmanı protokolüdür ve veri aktarımından önce bir bağlantı kurulmalıdır.
UDP'nin bağlanmasına gerek yoktur ve verileri hemen iletir.
2. Hizmet nesnesi
TCP, bire bir iki noktalı bir hizmettir, yani bir bağlantının yalnızca iki uç noktası vardır.
UDP bire bir, bire çok ve çoktan çoğa etkileşimli iletişimi destekler
3. Güvenilirlik
TCP, verileri güvenilir bir şekilde sunar ve veriler, hatalar, kayıplar, tekrarlar ve talepler olmadan talep üzerine ulaşabilir.
UDP, en iyi çabayı gösteren bir teslimattır ve verilerin güvenilir bir şekilde teslim edilmesini garanti etmez.
4. Tıkanıklık kontrolü, akış kontrolü
TCP, veri aktarımının güvenliğini sağlamak için tıkanıklık kontrolü ve akış kontrol mekanizmalarına sahiptir.
UDP yok Ağ çok yoğun olsa bile, UDP'nin gönderme oranını etkilemeyecektir.
5. Üstbilgi ek yükü
TCP başlığının uzunluğu uzundur ve belirli miktarda ek yük olacaktır. "Seçenek" alanı kullanılmadığında başlık 20 bayttır ve "seçenek" alanı kullanıldığında daha uzun olacaktır.
UDP başlığı yalnızca 8 bayta sahiptir ve sabittir ve düşük ek yüke sahiptir.
TCP ve UDP uygulama senaryoları:
TCP bağlantı odaklı olduğundan ve verilerin güvenilir bir şekilde teslim edilmesini garanti edebildiğinden, genellikle şunlar için kullanılır:
FTP dosya aktarımı
HTTP / HTTPS
UDP bağlantısız olmaya yönelik olduğundan, herhangi bir zamanda veri gönderebilir ve UDP'nin işlenmesi basit ve etkilidir, bu nedenle genellikle şunlar için kullanılır:
DNS, SNMP vb. Gibi az miktarda paketle iletişim
Video ve ses gibi multimedya iletişimi
Yayın iletişimi
UDP başlığında neden "başlık uzunluğu" alanı yok, ancak TCP başlığında "başlık uzunluğu" alanı var?
Bunun nedeni, TCP'nin değişken uzunluklu bir "seçenek" alanına sahip olması, ancak UDP başlığının uzunluğunun değişmemesi ve UDP başlığının uzunluğunu kaydetmek için ek bir alana gerek olmamasıdır.
UDP başlığında neden bir "paket uzunluğu" alanı var, ancak TCP başlığında "paket uzunluğu" alanı yok?
TCP'nin yük veri uzunluğunu nasıl hesapladığından bahsedeyim:
Bunlar arasında, IP toplam uzunluğu ve IP başlık uzunluğu IP başlık formatında bilinmektedir. TCP başlığının uzunluğu TCP başlık biçiminde bilinir, bu nedenle TCP verilerinin uzunluğu elde edilebilir.
Bu sırada herkes şaşırdı ve sordu: "UDP ayrıca IP katmanına dayalıdır, bu nedenle UDP'nin veri uzunluğu da bu formülle hesaplanabilir? Neden bir" paket uzunluğu "var? "
Bu soruyu sorduktan sonra, UDP "paket uzunluğunun" gereksiz olduğunu hissediyorum.
Ağ ekipmanı donanım tasarımı ve işlemesinin rahatlığı için, başlık uzunluğunun 4 baytlık bir tamsayı katı olması gerekir.
UDP "paket uzunluğu" alanı kaldırılırsa, UDP başlık uzunluğu 4 baytın tamsayı katı değildir, bu nedenle Kobayashi bunun 4 baytın tam sayı katı olan UDP başlık uzunluğunu tamamlayabileceğini ve ardından "paket uzunluğunu" tamamlayabileceğini düşünür. Alan.
TCP üç yönlü el sıkışma süreci ve durum geçişi
TCP, bağlantı yönelimli bir protokoldür, bu nedenle TCP kullanılmadan önce bir bağlantı kurulmalıdır ve bağlantı üç yönlü bir el sıkışma yoluyla kurulmalıdır.
Üç yönlü TCP anlaşması
Başlangıçta hem istemci hem de sunucu KAPALI durumdadır. İlk olarak, sunucu belirli bir bağlantı noktasını aktif olarak izler ve DİNLEME durumundadır.
İlk mesaj-SYN mesajı
İstemci seri numarasını (client_isn) rasgele başlatacak, bu seri numarasını TCP başlığının "Sıra Numarası" alanına yerleştirecek ve SYN paketini belirtmek için SYN bayrağını 1 olarak ayarlayacaktır. Sonra ilk SYN mesajını sunucuya gönderin, bu da sunucuya bir bağlantı başlatmak anlamına gelir Mesaj uygulama katmanı verilerini içermez Bundan sonra istemci SYN-SENT durumundadır.
İkinci mesaj-SYN + ACK mesajı
Sunucu istemciden SYN mesajını aldıktan sonra, önce sunucu kendi seri numarasını (server_isn) rasgele olarak başlatır, bu seri numarasını TCP başlığının "sıra numarası" alanına doldurur ve ardından TCP başlığının "onay yanıt numarası" alanını doldurur Client_isn + 1 girin ve ardından SYN ve ACK bayraklarını 1 olarak ayarlayın. Son olarak, mesaj istemciye gönderilir, mesaj uygulama katmanı verilerini içermez ve ardından sunucu SYN-RCVD durumundadır.
Üçüncü mesaj-ACK mesajı
İstemci, sunucu mesajını aldıktan sonra, son yanıt mesajıyla da sunucuya yanıt verir.İlk olarak, yanıt mesajının TCP başlığındaki ACK bayrağı 1'e ayarlanır ve ardından server_isn + 1'e "onay yanıt numarası" alanı doldurulur ve son olarak Mesaj sunucuya gönderilir, bu sefer mesaj istemciden sunucuya veri taşıyabilir ve ardından istemci KURULDU durumundadır.
Sunucu, istemciden yanıt mesajını aldıktan sonra, KURULUŞ durumuna da girer.
Yukarıdaki süreçten bulabilirsiniz Üçüncü tokalaşma veri taşıyabilir ve ilk iki tokalaşma veri taşıyamaz Bu da görüşmelerde sık sorulan bir sorudur.
Üç yönlü el sıkışma tamamlandıktan sonra, her iki taraf da KURULDU durumundadır, içtenlikle bağlantı kurulmuştur ve istemci ve sunucu birbirine veri gönderebilir.
Linux sisteminde TCP durumu nasıl kontrol edilir?
TCP'nin bağlantı durumu Linux'ta netstat -napt komutu ile kontrol edilebilir.
TCP bağlantı durumu görünümü
Neden üç yönlü bir el sıkışma? İki veya dört kez değil mi?
Herkesin sıklıkla yanıtladığı şeyin şu olduğuna inanıyorum: "Çünkü üç yönlü el sıkışma, her iki tarafın da alma ve gönderme yeteneğine sahip olmasını sağlayabilir."
Bu cevap sorun değil ama bu cevap tek yönlüdür ve asıl sebebi söylemiyor.
Daha önce TCP bağlantısının ne olduğunu biliyorduk:
Güvenilirlik ve akış kontrol bakımı sağlamak için kullanılan belirli durum bilgileri Soket, seri numarası ve pencere boyutu dahil olmak üzere bu bilgilerin birleşimine bağlantı adı verilir.
Yani önemli olan şey Üç yönlü el sıkışma neden soketi, seri numarasını ve pencere boyutunu başlatabilir ve bir TCP bağlantısı kurabilir?
Ardından, üç yönlü el sıkışmasının nedenlerini üç açıdan analiz edin:
Üç yönlü el sıkışma, geçmişte tekrarlanan bağlantıların başlatılmasını engelleyebilir (ana neden)
Yalnızca üç yönlü anlaşma, her iki tarafın da ilk seri numaralarını senkronize edebilir
Üç yönlü bir el sıkışma kaynak israfını önleyebilir
Neden 1: Geçmiş bağlantılardan kaçının
TCP bağlantılarının RFC 793 tarafından belirtilen üç yönlü anlaşmayı kullanmasının temel nedenine bir göz atalım:
Üç yönlü el sıkışmasının temel nedeni, eski çift bağlantı başlatmalarının karışıklığa neden olmasını önlemektir.
Basitçe söylemek gerekirse, üç el sıkışma Birincil neden, eski tekrarlanan bağlantı başlatmanın neden olduğu karışıklığı önlemektir.
Ağ ortamı karmaşık ve karmaşıktır.Çoğunlukla beklendiği gibi değildir.İlk gönderilen ilk veri paketi hedef ana bilgisayara gelir.Bunun aksine çok rahatsız edicidir.Eski veri paketlerini önce yapacak olan ağ tıkanıklığı gibi karmaşık nedenlere neden olabilir. Hedef ana bilgisayara ulaşmak için, bu durumda TCP'nin üç yönlü el sıkışmasından nasıl kaçınılır?
Tarihsel bağlantıdan kaçınmak için üç yönlü el sıkışma
İstemci, bir bağlantı kurmak için sürekli olarak birden çok SYN paketi gönderir. Ağ tıkanıklığı durumunda:
"Eski SYN mesajı" sunucuya "en yeni SYN" mesajından önce ulaşır;
Daha sonra sunucu şu anda istemciye bir SYN + ACK mesajı gönderecektir;
İstemci bunu aldıktan sonra, bunun geçmiş bir bağlantı olduğuna (seri numarasının süresi doldu veya zaman aşımına uğradı) kendi bağlamına göre karar verebilir, ardından istemci sunucuya bu bağlantının iptal edildiğini belirten bir RST mesajı gönderir.
İki yönlü bir el sıkışma bağlantısıysa, mevcut bağlantının geçmiş bir bağlantı olup olmadığını belirlemek imkansızdır.Üç yönlü bir el sıkışma için, istemci (gönderen) üçüncü mesajı göndermek üzereyken, istemcinin mevcut bağlantının olup olmadığını belirlemek için yeterli içeriği vardır. Tarihsel bağlantı:
Geçmiş bir bağlantı ise (seri numarasının süresi dolmuş veya zaman aşımına uğramış), üçüncü el sıkışmasında gönderilen mesaj, geçmiş bağlantıyı sonlandırmak için bir RST mesajıdır;
Geçmiş bir bağlantı değilse, üçüncü kez gönderilen mesaj bir ACK mesajıdır ve iletişim tarafları başarılı bir şekilde bir bağlantı kurar;
Bu nedenle, TCP'nin bağlantı kurmak için üç yönlü el sıkışmasını kullanmasının ana nedeni, Geçmiş bağlantının bağlantıyı başlatmasını önleyin.
Neden 2: Her iki tarafın ilk seri numaralarını senkronize edin
TCP protokolünün her iki iletişim tarafı da bir "seri numarası" tutmalıdır. Seri numarası, güvenilir iletim için önemli bir faktördür. İşlevi:
Alıcı, yinelenen verileri kaldırabilir;
Alıcı, veri paketinin sıra numarasına göre sırayla alabilir;
Karşı tarafın gönderilen veri paketlerinden hangisinin alındığını belirleyebilir;
Sıra numarasının TCP bağlantısında çok önemli bir rol oynadığı görülebilir, bu nedenle istemci "başlangıç sıra numarasını" taşıyan bir SYN mesajı gönderdiğinde, sunucunun istemcinin SYN mesajının olduğunu belirten bir ACK yanıt mesajı döndürmesi gerekir. Sunucu tarafından başarıyla alındığında, sunucu istemciye "ilk seri numarası" nı gönderdiğinde, yine de istemciden yanıt alması gerekir. Bu şekilde, her iki tarafın da ilk seri numaralarının güvenilir bir şekilde senkronize edilebilmesini sağlamak mümkündür.
Dört el sıkışma ve üç el sıkışma
Dört yönlü el sıkışma aslında her iki tarafın başlatma sıra numaralarını güvenilir bir şekilde senkronize edebilir, ancak ikinci ve üçüncü adımlar tek adımda optimize edilebildiği için "üç yönlü bir el sıkışma" olur.
İki el sıkışma, yalnızca bir tarafın ilk sıra numarasının diğer taraf tarafından başarılı bir şekilde alınabilmesini sağlar ve her iki tarafın da ilk sıra numarasının onaylanıp alınmasını sağlamanın bir yolu yoktur.
Sebep 3: Kaynak israfından kaçının
Yalnızca "iki el sıkışma" varsa, istemcinin SYN isteği bağlantısı ağda engellendiğinde, istemci ACK mesajını almaz, SYN'yi yeniden gönderir çünkü üçüncü bir el sıkışma olmadığı için sunucu istemcinin kendisini alıp almadığını bilmez Bir bağlantı kurmak için ACK sinyali gönderilir, bu nedenle her SYN alındığında, sadece aktif olarak önce bir bağlantı kurabilir Ne olacak?
İstemcinin SYN'si engellenmişse ve SYN mesajı tekrar tekrar birden çok kez gönderilirse, sunucu Gereksiz kaynak israfına neden olarak birden fazla gereksiz geçersiz bağlantı oluşturun.
İki el sıkışma kaynak israfına neden olur
Diğer bir deyişle, iki el sıkışma mesajın durumda kalmasına neden olur, sunucu tekrar tekrar gereksiz bağlantı isteği SYN paketlerini kabul eder ve bu da kaynakların tekrar tekrar tahsis edilmesine neden olur.
özet
TCP, üç yönlü bir el sıkışma yoluyla bir bağlantı kurduğunda Geçmiş bağlantıların kurulmasını önleyebilir, her iki taraf için gereksiz kaynak ek yükünü azaltabilir ve her iki tarafın da başlatma sıra numaralarını senkronize etmesine yardımcı olabilir. Sıra numarası, veri paketlerinin sırayla tekrarlanmamasını, atılmamasını ve iletilmemesini sağlayabilir.
"İki el sıkışma" ve "dört el sıkışma" kullanmama nedenleri:
"İki el sıkışma": Her iki tarafın da kaynak israfına neden olacak ve her iki tarafın seri numaralarını güvenilir bir şekilde senkronize edemeyen tarihsel bağlantının kurulmasını engelleyemez;
"Dört yönlü el sıkışma": Üç yönlü el sıkışma teorik olarak en az güvenilir bağlantı kurulumudur, bu nedenle daha fazla iletişim süresi kullanmaya gerek yoktur.
İstemci ve sunucunun ilk seri numaraları ISN neden farklı?
Çünkü ağdaki mesajlar Gecikecek, çoğaltılacak ve yeniden gönderilecek veya kaybolabilir , Bu, farklı bağlantılar arasında karşılıklı etkiye neden olacaktır, bu nedenle karşılıklı etkiden kaçınmak için, istemcinin ve sunucunun ilk sıra numaraları rastgele ve farklıdır.
İlk seri numarası ISN rastgele nasıl oluşturulur?
Başlangıç ISN'si saat tabanlıdır, her 4 milisaniye +1, bir devir 4,55 saat sürer.
RFC1948, daha iyi bir başlatma sıra numarası ISN rastgele oluşturma algoritması önerdi.
ISN = M + F (localhost, localport, remotehost, remoteport)
M bir zamanlayıcıdır, bu zamanlayıcı her 4 milisaniyede 1 artar.
F, kaynak IP, hedef IP, kaynak bağlantı noktası ve hedef bağlantı noktasına göre rastgele bir değer üreten bir Karma algoritmasıdır. Hash algoritmasının dışarıdan kolayca hesaplanamadığından emin olmak için MD5 algoritmasını kullanmak daha iyi bir seçimdir.
IP katmanı parçalanacağına göre, TCP katmanı neden MSS'ye ihtiyaç duyar?
Önce MTU ve MSS'yi tanıyalım
MTU ve MSS
MTU: Bir ağ paketinin maksimum uzunluğu, Ethernet'te genellikle 1500 bayt;
MSS: IP ve TCP başlıklarını kaldırdıktan sonra, bir ağ paketinin içerebileceği maksimum TCP verisi uzunluğu;
TCP mesajının tamamı (başlık + veri) parçalanma için IP katmanına aktarılırsa ne olur?
IP katmanında gönderilecek MTU boyutunu aşan bir veri parçası (TCP başlığı + TCP verileri) olduğunda, IP katmanının her bir parçanın MTU'dan daha küçük olmasını sağlamak için verileri parçalara ayırması ve birkaç parçaya bölmesi gerekir. Bir IP datagramı parçalandıktan sonra, hedef ana bilgisayarın IP katmanı tarafından yeniden birleştirilir ve ardından üst TCP taşıma katmanına aktarılır.
Bu düzenli görünüyor, ama gizli tehlikeler var. Daha sonra bir IP parçası kaybolursa, tüm IP paketinin tüm parçalarının yeniden iletilmesi gerekir.
IP katmanının kendisi bir zaman aşımı yeniden iletim mekanizmasına sahip olmadığından, zaman aşımı ve yeniden iletimden sorumlu olan taşıma katmanının TCP'sidir.
Alıcı, TCP mesajının bir parçasının (başlık + veri) eksik olduğunu tespit ettiğinde, diğer tarafa ACK'ya yanıt vermeyecektir. Ardından, gönderenin TCP'si bir zaman aşımından sonra tüm TCP mesajını (başlık + veri) yeniden iletecektir. ) .
Bu nedenle, IP katmanı tarafından parçalı iletimin çok verimsiz olduğu bilinebilir.
Bu nedenle, en iyi aktarım performansını elde etmek için, TCP protokolü genellikle bir bağlantı kurarken her iki tarafın MSS değerini müzakere eder.TCP katmanı, verilerin MSS'yi aştığını tespit ettiğinde, ilk olarak parçalanır ve tabii ki oluşturduğu IP paketinin uzunluğu MTU'dan daha büyük olmayacağı için IP parçalanması doğal olarak gereksizdir.
El sıkışma sırasında MSS anlaşması
TCP katman parçalanmasından sonra, bir TCP parçası kaybolursa, tüm parçaları yeniden iletmek yerine yeniden iletim birimi de MSS'dir ve bu da yeniden iletimin verimliliğini büyük ölçüde artırır.
SYN saldırısı nedir? SYN saldırılarından nasıl kaçınılır?
SYN saldırısı
TCP bağlantı kurulumunun üç yönlü bir el sıkışma gerektirdiğini hepimiz biliyoruz.Saldırganın kısa sürede farklı IP adreslerine sahip SYN paketleri taklit ettiğini varsayarsak, sunucu her SYN paketi aldığında SYN_RCVD durumuna girer ancak sunucu ACK + SYN paketleri gönderir. Bilinmeyen IP ana bilgisayarından ACK yanıtı alınamayan metin, SYN alma kuyruğu sunucu dolu (bağlantısız kuyruk) , Sunucunun normal kullanıcılara hizmet verememesini sağlamak.
SYN saldırısı
SYN saldırısından kaçının yöntem bir
Çözümlerden biri, kuyruk boyutunu ve kuyruk dolduğunda ne yapılacağını kontrol etmek için Linux çekirdek parametrelerini değiştirmektir.
Ağ kartı, veri paketlerini çekirdek işlem hızından daha hızlı aldığında, bu veri paketlerini kaydetmek için bir sıra olacaktır. Aşağıdaki parametreler kuyruğun maksimum değerini kontrol eder:
net.core.netdev_max_backlog
SYN_RCVD durumunda maksimum bağlantı sayısı:
net.ipv4.tcp_max_syn_backlog
İşlem kapasitesi aşıldığında, RST'yi doğrudan yeni SYN'ye döndürün ve bağlantıyı atın:
net.ipv4.tcp_abort_on_overflow
İkinci SYN saldırısından kaçının
İlk olarak Linux çekirdeğinin SYN (bitmemiş bağlantı kurma) kuyruğunun ve Accpet (tamamlanmış bağlantı kurulumu) kuyruğunun nasıl çalıştığına bakalım.
Normal Süreç
Normal Süreç:
Sunucu, istemciden SYN mesajını aldığında, çekirdeğin "SYN kuyruğuna" eklenecektir;
Ardından istemciye SYN + ACK gönderin ve istemcinin bir ACK mesajıyla yanıt vermesini bekleyin;
Sunucu ACK mesajını aldıktan sonra onu "SYN kuyruğundan" kaldırır ve "Kabul kuyruğuna" koyar;
Uygulama, accpet soket arabirimini çağırarak bağlantıyı "Accept Queue" dan alır.
Uygulama çok yavaş
Uygulama çok yavaş:
Uygulama çok yavaşsa, "Kabul Kuyruğu" nun dolu olmasına neden olur.
SYN saldırısı altında
SYN tarafından saldırıya uğradı:
SYN tarafından saldırıya uğramaya devam ederseniz, "SYN kuyruğu" dolacaktır.
Tcp_syncookies yöntemi SYN saldırılarıyla başa çıkabilir:
net.ipv4.tcp_syncookies = 1
tcp_syncookies, SYN saldırılarına yanıt verir
"SYN kuyruğu" dolduğunda, sonraki sunucu SYN paketlerini alır ve "SYN kuyruğuna" girmez;
Bir çerez değeri hesaplayın ve SYN + ACK'daki "seri numarası" ile müşteriye iade edin,
Sunucu istemciden yanıt mesajını aldığında, sunucu ACK paketinin geçerliliğini kontrol edecektir. Yasal ise, doğrudan "Kabul Sırası" na koyun.
Son olarak, uygulama accpet soket arabirimini çağırarak bağlantıyı "Kabul Kuyruğu" ndan alır.
TCP dört dalgalı el süreci ve durum geçişi
Dünyada kalıcı bir ziyafet yoktur ve aynı şey TCP bağlantıları için de geçerlidir, TCP bağlantıları dört kez el sallayarak yapılır.
Her iki taraf da aktif olarak bağlantıyı kesebilir ve ana bilgisayardaki "kaynaklar" bağlantı kesildikten sonra serbest bırakılır.
İstemci, dört kez dalgalanan TCP bağlantısını aktif olarak kapatır
İstemci bağlantıyı kapatmak niyetindedir Bu anda, TCP başlığında FIN bayrağı biti 1'e ayarlanmış bir mesaj, yani bir FIN mesajı gönderir ve ardından istemci FIN_WAIT_1 durumuna girer.
Mesajı aldıktan sonra, sunucu istemciye bir ACK yanıt mesajı gönderir ve ardından sunucu CLOSED_WAIT durumuna girer.
İstemci sunucudan ACK yanıt mesajını aldıktan sonra FIN_WAIT_2 durumuna girer.
Sunucunun verileri işlemesini bekledikten sonra, istemciye bir FIN mesajı da gönderir ve ardından sunucu LAST_ACK durumuna girer.
Sunucudan FIN mesajını aldıktan sonra, istemci bir ACK yanıt mesajı verir ve ardından TIME_WAIT durumuna girer.
Sunucu, ACK yanıt mesajını aldıktan sonra, KAPAT durumuna girer ve bu noktada sunucu bağlantıyı kapatır.
2MSL süresinden sonra, istemci otomatik olarak KAPAT durumuna girer Bu noktada istemci de bağlantıyı kapatmıştır.
Gördüğünüz gibi, her yön için bir SON ve bir ACK gerekir, bu nedenle genellikle dört dalga olarak adlandırılır.
Burada dikkat edilmesi gereken bir şey şudur: Yalnızca bağlantıyı aktif olarak kapatanlar TIME_WAIT durumuna sahip olacaktır.
Neden dört kez el sallamam gerekiyor?
Her iki tarafı dört kez sallayarak FIN paketlerini gönderme sürecine dönüp baktığımızda, bunun neden dört kez gerekli olduğunu anlayabilirsiniz.
Bağlantı kapatıldığında, istemci sunucuya bir FIN gönderdiğinde, bu yalnızca istemcinin artık veri göndermediği ancak yine de veri alabileceği anlamına gelir.
Sunucu istemciden FIN mesajını aldığında, önce bir ACK yanıt mesajı döndürür ve sunucu hala işlenecek ve gönderilecek veriye sahip olabilir.Sunucu artık veri göndermediğinde, istemciye onay vermesi için FIN mesajını gönderecektir. Şimdi bağlantıyı kapatın.
Yukarıdaki işlemden, sunucunun genellikle veri aktarımının ve işlemenin tamamlanmasını beklemesi gerektiği, bu nedenle sunucunun ACK ve FIN'i genellikle ayrı olarak gönderilir, bu da üç yönlü el sıkışmasından bir kez daha fazladır.
TIME_WAIT 2MSL bekleme süresi neden?
MSL, Maksimum Segment Ömrüdür, bir mesajın maksimum yaşam süresi. Herhangi bir mesajın ağda bulunabileceği en uzun süredir. Bu sürenin sonunda mesaj silinecektir. TCP paketleri IP protokolüne dayandığından ve IP üstbilgisinde bir IP datagramının geçebileceği maksimum yol sayısı olan bir TTL alanı vardır. Bu değer, onu işleyen her yönlendiriciden sonra 1 azalır. Değer 0 olduğunda, veriler Mesaj atılacak ve kaynak sunucuyu bilgilendirmek için bir ICMP mesajı gönderilecektir.
MSL ve TTL arasındaki fark: MSL'nin birimi zamandır, TTL ise yol atlama sayısıdır. Bu nedenle, mesajın doğal olarak yok edildiğinden emin olmak için MSL, TTL'nin 0'a harcadığı zamandan büyük veya ona eşit olmalıdır.
TIME_WAIT, MSL'nin 2 katı bekler. Daha makul bir açıklama şudur: Ağda göndericiden gelen veri paketleri olabilir. Bu göndericinin veri paketleri alıcı tarafından işlendiğinde, diğer tarafa bir yanıt gönderecekler, bu nedenle bir defaya mahsus beklemeleri gerekir. 2 kez.
Örneğin, pasif kapanış tarafı, bağlantının kesilmesinin son ACK mesajını almazsa, Fin mesajının bir zaman aşımı yeniden iletimini tetikleyecektir.Diğer taraf FIN'i aldıktan sonra, pasif kapanış tarafına sadece bir yöne ve diğerine giderek bir ACK'yı yeniden gönderecektir. 2 MSL.
İstemci FIN aldıktan sonra ACK gönderdiğinde 2MSL zamanı başlar. TIME-WAIT süresi içinde, istemcinin ACK'sı sunucuya iletilmediğinden ve istemci sunucu tarafından yeniden iletilen FIN mesajını aldığından, 2MSL süresi tekrar sayılacaktır.
Linux sistemlerinde, 2MSL varsayılan olarak 60 saniyedir, dolayısıyla bir MSL 30 saniyedir. Linux sistemi, 60 saniyelik sabit bir süre için TIME_WAIT'de kalır.
Linux çekirdek kodunda tanımlanan ad TCP_TIMEWAIT_LEN'dir:
#define TCP_TIMEWAIT_LEN (60 * HZ) / * TIME-WAIT durumunu ortadan kaldırmak için ne kadar bekleneceği, yaklaşık 60 saniye * /
TIME_WAIT'in zaman uzunluğunu değiştirmek isterseniz, yalnızca Linux çekirdek kodundaki TCP_TIMEWAIT_LEN değerini değiştirebilir ve Linux çekirdeğini yeniden derleyebilirsiniz.
TIME_WAIT durumu neden gerekli?
Yalnızca bağlantının kapanmasını başlatan taraf TIME-WAIT durumuna sahip olacaktır.
TIME-WAIT durumu iki ana nedenden dolayı gereklidir:
Aynı "dörtlü" pakete sahip "eski" paketlerin alınmasını önleyin;
"Bağlantıyı pasif olarak kapatan" tarafın doğru şekilde kapatılabilmesini sağlayın, yani nihai ACK'nın pasif olarak kapatılan taraf tarafından alınabilmesini ve böylece normal şekilde kapanmasına yardımcı olun;
Neden 1: Eski bağlantılardan gelen veri paketlerini önleyin
TIME-WAIT'in bekleme süresi olmadığını veya sürenin çok kısa olduğunu varsayarsak, geciken paket geldikten sonra ne olacak?
Alınan geçmiş veriler istisnası
Yukarıdaki şekilde gösterildiği gibi, sunucunun sarı kutusu, ağ tarafından geciktirilen bağlantıyı kapatmadan önce SEQ = 301 mesajını gönderir.
Bu sırada, aynı bağlantı noktasıyla TCP bağlantısı yeniden kullanıldıktan sonra, gecikmiş SEQ = 301 istemciye ulaşır, ardından istemci normal olarak süresi dolan mesajı alabilir ve bu da veri karışıklığı gibi ciddi sorunlara neden olur.
Bu nedenle, TCP böyle bir mekanizma tasarlamıştır. 2MSL'den sonra, Her iki yöndeki veri paketlerinin atılmasına neden olmak yeterlidir, böylece orijinal olarak bağlanan veri paketleri ağda doğal olarak kaybolur ve yeniden ortaya çıkan veri paketleri yeni kurulan bağlantı tarafından oluşturulmalıdır.
Neden 2: Bağlantının düzgün şekilde kapatıldığından emin olun
RFC 793'e göre TIME-WAIT'in diğer bir önemli işlevi şudur:
TIME-WAIT - uzak TCP'nin bağlantı sonlandırma talebinin onayını aldığından emin olmak için yeterince zaman geçmesini beklemeyi temsil eder.
Başka bir deyişle, TIME-WAIT işlevinin işlevi Nihai ACK'nın pasif kapatan taraf tarafından alınmasını sağlamak için yeterince bekleyin, böylece normal şekilde kapanmasına yardımcı olun.
TIME-WAIT'in bekleme süresi olmadığını veya sürenin çok kısa olduğunu varsayarsak, bağlantının kesilmesi hangi sorunlara neden olur?
Normal bağlantı kesilmesini sağlamayan bir istisna
İstemcinin yukarıdaki kırmızı kutuya dört kez salladığı son ACK mesajı ağda kaybolursa, istemci TIME-WAIT çok kısaysa veya değilse, doğrudan KAPAT durumuna girecek ve sunucu Her zaman LASE-ACK durumunda.
İstemci bir bağlantı kurmak için bir SYN istek mesajı başlattığında, sunucu istemciye bir RST mesajı gönderecek ve bağlantı kurma işlemi sona erdirilecektir.
TIME-WAIT yeterince uzun beklerse, iki durum ortaya çıkar:
Sunucu normalde dört kez dalgalanan son ACK mesajını alır ve sunucu bağlantıyı normal şekilde kapatır.
Sunucu, dört kez dalgalanan son ACK mesajını almadığında, FIN bağlantı kapama mesajını yeniden gönderecek ve yeni bir ACK mesajını bekleyecektir.
Dolayısıyla, istemci TIME-WAIT durumunda 2MSL'yi bekledikten sonra, Her iki bağlantının da normal şekilde kapatılabildiğinden emin olun.
Çok fazla TIME_WAIT kullanmanın zararı nedir?
Sunucunun TIME-WAIT durumunda bir TCP'si varsa, bu, sunucu tarafından başlatılan bağlantı kesme isteği anlamına gelir.
Aşırı TIME-WAIT durumunun iki ana tehlikesi vardır:
Birincisi, bellek kaynağı işgalidir;
İkincisi, bağlantı noktası kaynaklarının işgalidir Bir TCP bağlantısı en az bir yerel bağlantı noktasını kullanır;
İkinci tehlike ciddi sonuçlara neden olabilir. Bağlantı noktası kaynaklarının da sınırlı olduğunu bilmelisiniz.Genel olarak, açılabilen bağlantı noktaları 32768 61000'dir ve aşağıdaki parametre ayarlarıyla da belirtilebilir:
net.ipv4.ip_local_port_range
Sunucunun TIME_WAIT durumu çok fazlaysa ve tüm bağlantı noktası kaynaklarını kullanıyorsa, yeni bir bağlantı oluşturulamamasına neden olur.
TIME_WAIT nasıl optimize edilir?
İşte TIME-WAIT'i optimize etmenin tümünün avantajları ve dezavantajları olan birkaç yolu:
Net.ipv4.tcp_tw_reuse ve net.ipv4.tcp_timestamps seçeneklerini açın;
net.ipv4.tcp_max_tw_buckets
Programda SO_LINGER kullanılır ve uygulama kapatmak için RST kullanmaya zorlanır.
Yöntem 1: net.ipv4.tcp_tw_reuse ve tcp_timestamps
Aşağıdaki Linux çekirdek parametreleri etkinleştirildikten sonra, TIME_WAIT içindeki soket yeni bağlantılar için yeniden kullanılabilir.
net.ipv4.tcp_tw_reuse = 1
Bu seçeneği kullanmak için başka bir ön koşul daha var, TCP zaman damgası desteğini açmanız gerekiyor, yani
net.ipv4.tcp_timestamps = 1 (varsayılan 1'dir)
Bu zaman damgası alanı, TCP göndericisinin geçerli zaman damgasını ve eşten alınan en son zaman damgasını kaydetmek için TCP başlığının "seçeneklerinde" kullanılır.
Zaman damgalarının kullanılmaya başlanması nedeniyle, daha önce bahsettiğimiz 2MSL sorunu artık mevcut değildir, çünkü yinelenen veri paketleri zaman damgasının sona ermesi nedeniyle doğal olarak atılacaktır.
Sıcak hatırlatma: net.ipv4.tcp_tw_reuse dikkatli kullanılmalıdır, çünkü bunun kullanılması zaman damgası desteğini etkinleştirmelidir net.ipv4.tcp_timestamps. İstemci ve sunucu ana bilgisayar zamanı senkronize edilmediğinde, istemci tarafından gönderilen mesaj doğrudan Reddet. Xiaolin, işinde bununla karşılaştı. . . Uzun süre kontrol edildi
Yöntem 2: net.ipv4.tcp_max_tw_buckets
Bu değer varsayılan olarak 18000'dir Sistemdeki TIME_WAIT bağlantısı bu değeri aştığında, sistem tüm TIME_WAIT bağlantı durumlarını sıfırlayacaktır.
Bu yöntem çok şiddetlidir ve semptomları tedavi eder, ancak temel nedeni değil, çözdüğünden daha fazla sorun getirir, bu nedenle önerilmez.
Yöntem 3: Programda SO_LINGER kullanın
Soket seçeneğini ayarlayarak bağlantıyı kapatmak için yakın arama davranışını ayarlayabiliriz.
struct oyalanacak so_linger; so_linger.l_onoff = 1; so_linger.l_linger = 0; setsockopt (s, SOL_SOCKET, SO_LINGER, so_linger, sizeof (so_linger));Eğer l_onoff sıfır değilse ve l_linger değeri 0 ise, o zaman close çağrıldıktan sonra, hemen karşı uca bir RST bayrağı gönderecek ve TCP bağlantısı dört dalgalı eli atlayacak ve böylece TIME_WAIT durumunu atlayacak ve doğrudan kapatacaktır.
Ancak bu, TIME_WAIT durumunu geçme olanağı sağlar, ancak çok tehlikeli bir davranıştır ve terfi etmeye değmez.
Ya bağlantı kurulursa ancak müşteri aniden başarısız olursa?
TCP'nin bir mekanizması canlı tutma mekanizmasıdır. Bu mekanizmanın prensibi aşağıdaki gibidir:
Bir zaman periyodu tanımlayın Bu zaman periyodu sırasında, bağlantı ile ilgili bir aktivite yoksa, TCP canlı tutma mekanizması çalışmaya başlayacaktır.Her zaman aralığında, bir yoklama mesajı gönderilir.Sorgu mesajı çok az veri içerir. Birkaç ardışık algılama paketi için yanıt alınmazsa, geçerli TCP bağlantısı ölü kabul edilir ve sistem çekirdeği, hata bilgisini üst katman uygulamasına bildirir.
Canlı tutma süresini, canlı tutma saptamalarının sayısını ve canlı tutma algılamalarının zaman aralığını ayarlamak için Linux çekirdeğinde karşılık gelen parametreler vardır. Aşağıdakiler varsayılan değerlerdir:
net.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_keepalive_probes = 9tcp_keepalive_time = 7200: canlı tutma süresinin 7200 saniye (2 saat) olduğunu gösterir, yani 2 saat içinde bağlantıyla ilgili bir aktivite olmazsa, canlı tutma mekanizmasının etkinleştirileceğini gösterir
tcp_keepalive_intvl = 75: her algılama arasındaki aralığın 75 saniye olduğu anlamına gelir;
tcp_keepalive_probes = 9: 9 algılamadan sonra yanıt gelmediği ve diğer tarafın ulaşılamaz olarak değerlendirildiği ve dolayısıyla mevcut bağlantıyı kesdiği anlamına gelir.
Yani, bir Linux sisteminde "ölü" bir bağlantı bulmak en az 2 saat, 11 dakika ve 15 saniye sürer.
Bu süre biraz uzun, yukarıdaki canlı tutma ile ilgili parametreleri gerçek ihtiyaçlara göre de ayarlayabiliriz.
TCP canlı tutma etkinleştirilmişse, aşağıdaki durumların dikkate alınması gerekir:
Birincisi, eş programın normal çalışmasıdır. TCP canlı tutma algılama mesajı eşe gönderildiğinde, eş normal yanıt verir, böylece TCP canlı tutma süresi sıfırlanır ve bir sonraki TCP canlı tutma süresinin gelmesini bekler.
İkincisi, eş programın çökmesi ve yeniden başlatılmasıdır. TCP canlı tutma algılama paketi eşe gönderildiğinde, eş yanıt verebilir, ancak bağlantı hakkında geçerli bir bilgi olmadığından, bir RST paketi oluşturulur, böylece yakında TCP bağlantısının sıfırlandığı bulunacaktır.
Üçüncüsü, karşı uçtaki programın çökmesi veya karşı uçtaki mesajın başka nedenlerle ulaşılamaz olmasına neden olmasıdır. TCP canlı tutma algılama mesajı karşı uca gönderildiğinde, yanıt alınmaz.Ardı ardına birkaç kez ve canlı tutma algılamalarının sayısına ulaşıldıktan sonra, TCP, TCP bağlantısının kesildiğini bildirir.
Soket TCP için nasıl programlanır?
İstemci ve sunucu TCP protokolüne göre çalışır
Sunucu ve istemci soketi başlatır ve dosya tanımlayıcısını alır;
Sunucu, IP adresine ve bağlantı noktasına bağlanmak için bind'i çağırır;
Sunucu izlemek için dinle çağırır;
Sunucu çağrıları kabul eder ve istemcinin bağlanmasını bekler;
İstemci, sunucunun adresine ve bağlantı noktasına bir bağlantı isteği başlatmak için connect çağırır;
Kabul sunucusu, iletim için kullanılan soketin dosya tanımlayıcısını döndürür;
İstemci verileri yazmak için yaz, sunucu verileri okumak için oku çağırır;
close read EOF close
accept socket
socket socket socket socket socket
read write
listen backlog
Linux
SYN SYN SYN_RCVD
Accpet TCP ESTABLISHED
SYN Accpet
int listen (int socketfd, int backlog)
socketfd socketfd
backlog
Linux backlog SYN
Linux 2.2 backlog accept backlog accept
accept
SYN client_isn SYNC_SENT
ACK client_isn+1 SYN client_isn SYN server_isn SYNC_RCVD
ACK connect ESTABLISHED SYN server_isn+1
accept ESTABLISHED
connect accept
close
close
close
close FIN FIN_WAIT_1
FIN TCP FIN EOF read FIN EOF EOF CLOSE_WAIT
EOF close FIN LAST_ACK
FIN ACK TIME_WAIT
ACK CLOSE
2MSL CLOSED
TCP TCP
Goodbye
referans:
...
...
-. .
TCP/IP 1. .
TCP/IP..
https://www.rfc-editor.org/rfc/rfc793.html
https://draveness.me/whys-the-design-tcp-three-way-handshake
https://draveness.me/whys-the-design-tcp-time-wait
360 36
2020 5
10 SVG oluşturma
Microsoft bir kişi için bir şirket mi satın alıyor? Sony programlarını kırın, hacker romanları yazın ve sağlam program hayatını izleyin!
Makine öğrenimi proje şablonu: Makine öğrenimi projesinin 6 temel adımı
IBM, Microsoft, Apple, Google, Samsung ... blok zincirindeki teknoloji devleri şimdiden çok şey yaptı!
Kıdemli programcının özeti: Linux sürecini analiz etmek için 6 yöntem, size hepsini anlatacağım
Bugünün refahı: yorum alanı seçildi, çevrimiçi 299 yuan değerinde "2020 AI Geliştiricileri Konferansı" nı alabilirsiniz Bir canlı bilet . Parmaklarınızı hareket ettirin ve söylemek istediklerinizi yazın.