Neden 3 yollu el sıkışmasına ihtiyacımız var? Neden sadece 2 yönlü değil?


124

TCP 3 yollu el sıkışma şöyle çalışır:

Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server

Neden sadece bu değil?

Client ------SYN-----> Server
Client <-----ACK------ Server

24
Neden bir el sıkışmasına bile ihtiyacımız var? Mesaj neden ilk paketle birlikte gönderilemiyor?
Mehrdad

4
El sıkışmayı atlamak istiyorsanız, bunun yerine UDP kullanabilirsiniz.
OzNetNerd 4:15

5
@Mehrdad, kendi sorunuz varsa, lütfen kendi mesajınızı göndermek için sayfanın üstündeki Soru Sor bağlantısını kullanın.
YLearn

40
@YLearn: Üzgünüm, bu gerçekten benim için bir sorun değil, tam anlamıyla soruda ifade edilenden biraz daha derine inen cevaplar vermeye okuyucuları motive etmekti.
Mehrdad

3
TCP Hızlı Açmayı unutma (RFC 7413)
Alnitak

Yanıtlar:


159

El sıkışmasını gerçekte ne yaptığına ayırın.

TCP’de, iki taraf bir Sıra numarası kullanarak ne gönderdiklerini takip eder. Etkili, gönderilen her şeyin çalışan bir bayt sayısı olmasıyla sonuçlanır. Alıcı taraf, karşı tarafın ne aldığını kabul etmek için sıra numarasını kullanabilir.

Ancak dizi numarası 0'dan başlamaz. Rastgele seçilen bir değer olan ISN'den (İlk Sıra Numarası) başlar. Ve TCP iki yönlü bir iletişim olduğundan, her iki taraf da "konuşabilir" ve bu nedenle her ikisi de rastgele başlangıç ​​Sıra Numarası olarak bir ISN üretmelidir. Bu da iki tarafın da diğer tarafa başlangıçtaki ISN'lerini bildirmeleri gerektiği anlamına gelir.

Öyleyse, Alice ile Bob arasındaki bir TCP sohbetinin başlaması için bu olay dizisiyle bitiyorsunuz:

Alice ---> Bob    SYNchronize with my Initial Sequence Number of X
Alice <--- Bob    I received your syn, I ACKnowledge that I am ready for [X+1]
Alice <--- Bob    SYNchronize with my Initial Sequence Number of Y
Alice ---> Bob    I received your syn, I ACKnowledge that I am ready for [Y+1]

Dikkat, dört olay gerçekleşiyor:

  1. Alice bir ISN seçer ve onu Bob ile senkronize eder.
  2. Bob AC ISN'yi tanıyor .
  3. Bob bir ISN seçer ve onu Alice ile senkronize eder.
  4. Alice AC ISN'yi tanıdı .

Gerçekte, aslında ortadaki iki olay (# 2 ve # 3) aynı pakette gerçekleşiyor. Bir paketi yapan SYNveya ACKbasitçe, her TCP başlığının içinde açılmış veya kapatılmış bir ikili bayrak olduğundan, bu bayrakların her ikisinin de aynı pakette etkinleştirilmesini engelleyen hiçbir şey yoktur. Böylece üç yollu el sıkışma sona erer:

Bob <--- Alice         SYN
Bob ---> Alice     SYN ACK 
Bob <--- Alice     ACK     

Her iki yönde de "SYN" ve "ACK" olmak üzere iki örneğe dikkat edin.


Öyleyse sorunuza geri dönelim, neden sadece iki yönlü bir el sıkışma kullanmıyorsunuz? Kısa cevap, iki yönlü el sıkışmasının yalnızca bir tarafın ISN kurmasına ve diğer tarafın bunu onaylamasına izin vermesidir. Bu, yalnızca bir tarafın veri gönderebileceği anlamına gelir.

Ancak TCP, iki yönlü bir iletişim protokolüdür; bu, her iki ucun da güvenilir bir şekilde veri gönderebilmesi gerektiği anlamına gelir. Her iki tarafın da bir ISN kurması ve her iki tarafın da diğerinin ISN'sini kabul etmesi gerekir.

Sonuç olarak, elinizde olan şey, iki yönlü el sıkışmasının tam olarak sizin tarifinizdir, ancak her yöne . Dolayısıyla, dört olay meydana geliyor. Ve yine, ortadaki iki bayrak aynı pakette olur. Gibi üç paket tam bir TCP bağlantı başlatma işleminde yer almaktadır.


6
Neden ISN'lere ihtiyacımız var? İnsanların buna ihtiyacı yok, neden bilgisayarlar var? Bunun bir kanıtı var mı, yoksa elverişli oldukları için onlara mı sahibiz?
Mehrdad,

19
@Mehrdad: Yeniden iletimlerin doğru çalışması için (veya gerçekten de) sıra numaralarına ihtiyacınız var. ISN, dizi tahmin saldırıları nedeniyle yalnızca sıfır olamaz .
Kevin

4
@Mehrdad Sohbet odası mutlaka 'gerçek zamanlı' olmak zorunda değildir, birbirimize mesaj bırakabiliriz. Başka bir yere yönlendirmeyi düşündüğüm sebep, şimdi farklı bir soru sormanız. OP “neden 2 yerine 3 yollu el sıkışma” diye sordu, ama şimdi “neden sıralı sayılara ihtiyacımız var” sorusunu soruyorsun, bu farklı. Bu konuyu raydan çıkarmak yerine, diğer soruyu sohbette tartışmamız gerektiğini düşündüm. Alternatif olarak , yeni bir soru gönderebilirsiniz, bazı iyi cevaplar net olacak eminim.
Eddie

4
Harika, özlü cevap. "ACK SYN" okumak temel olarak yanlıştır, ancak siz bunu +1 olarak açıkladınız.
Lilienthal

3
Göre RFC 793, İletim Kontrol Protokolü : " üç yönlü el sıkışma başlıca sebebi, karışıklığa yol açmasını eski yinelenmiş bağlantı ilklendirmelerinin önlemektir. "
Ron Maupin

23

Her iki tarafın gerekir, çünkü üç yönlü el sıkışma gereklidir syn chronize kendi iletimi sırasında kullanılan kendi kademeli bir dizi numaralarını. Bunun için, her biri (ki bu da) bir rastgele değer olarak ayarlanmış, bir sıra numarası bir SYN gönderir n o olduğu, bildirim ayarlanmış bir sıra numarası ile bir ACK bölümü yoluyla, diğer tarafın nowledged n + 1 .


Onay neden gerekli?
Paŭlo Ebermann 4:15

4
@ PaŭloEbermann: Aksi halde Sunucu, istemcinin SYN'yi alıp almadığı konusunda hiçbir fikri yoktur ve müşterinin bunu alması önemlidir.
Mooing Duck

2
@ PaŭloEbermann Bunu kanıtlamak için, ACK adımı [X + 1] ile onaylamaktır. - Eddiecevabına yaptığı yorumdan alıntı .
smwikipedia

14

Bağlantının çalışması için, her bir tarafın diğer tarafa paket gönderebildiğini doğrulaması gerekir. Diğer tarafa bir paket aldığınızdan emin olmanın tek yolu, onlardan bir paket almaktır, tanımı gereği, gönderdiğiniz paket geçmeden gönderilemez . TCP esasen bunun için mesajların iki çeşit kullanır: SYN ve (SYN SYN sahasına girdi kanıtlamak için, içinden alır sonra ancak gönderilen alır) ACK (bu paket sayesinde var kanıt istemek için). Aslında üçüncü tür bir mesaj var, ancak bir dakika sonra buna varacağız.

Bağlantı başlamadan önce, iki taraf da diğeriyle ilgili hiçbir şey bilmiyor. İstemci, iletilerinin ulaşabileceğinin kanıtını istemek için sunucuya bir SYN paketi gönderir . Bu her iki kişiye de bir şey söylemiyor, ancak el sıkışmasının ilk adımı.

SYN geçerse, sunucu müşterinin kendisine paket gönderebileceğini bilir, çünkü tam olarak gerçekleşti. Ancak bu sunucunun paketleri geri gönderebileceğini kanıtlamaz: istemciler birçok nedenden dolayı SYN'ler gönderebilir . Bu yüzden sunucunun istemciye iki ileti göndermesi gerekir: bir ACK (SYN'nin geçtiğini kanıtlamak için) ve bir SYN (kendi ACK'sini istemek için). Ağ trafiğini azaltacaksanız, TCP bu iki mesajı bir-bir SYN-ACK mesajında ​​birleştirir. Bu, el sıkışmasının ikinci adımıdır.

Bir SYN-ACK bir ACK olduğundan, istemci artık sunucuya paket gönderebileceğinden emindir. Bir SYN-ACK bir SYN olduğundan, sunucunun bu mesajın geçtiğinin kanıtı istediğini de bilir. Bu yüzden bir ACK'yı geri gönderir: bu sefer sadece düz bir ACK, çünkü paketlerinin geçebileceği bir kanıtı olması gerekmiyor. Bu el sıkışma son adımdır: istemcisi artık paketler her iki yöne gidebilir biliyor ve sunucu olduğunu hemen (o bildiği için ACK geçeceği) bu anlamaya.

Bu ACK geçtikten sonra, sunucu artık müşteriye paket gönderebileceğini biliyor . Ayrıca müşterinin bunu bildiğini de bilir, böylece hemen veri göndermeye başlayabilir. El sıkışma tamamlandı. İyi bir kanalımız var.

Kesin konuşursak, iyi bir kanalımız olduğundan emin olamayız . Sırf bu paketler dizisinin içinden geçmesi, diğerlerinin de yapacağı kesin garantiyi vermez . Sonsuz sayıda SYN ve ACK göndermeden ve hiçbir şey yapamayacağımızı ispatlayamayız, bu yüzden bu gerçekten pratik bir seçenek değildir. Ancak pratikte, üç adımın çoğu amaç için yeterince iyi olduğu ortaya çıktı .


Bu doğru değildir: "bir ACK (yalnızca SYN'lere yanıt olarak gönderilen ve bu nedenle SYN'nin geçtiğini kanıtlar)." Yalnızca her bir uçtan gönderilen ilk paket SYN bayrağı kümesine sahiptir ve 3 yollu el sıkışmasının ilk paketinden başka tüm paketlerde ACK bayrağı ayarlanmıştır. İlk paket ACK yapamaz çünkü ikinci parti henüz SYNed yapmamıştır, ancak ilk paketten sonraki her paket diğer uçtan ne alınmışsa, herhangi bir verinin geri gönderilip gönderilmeyeceğini almalıdır.
Monty Harder

Teşekkürler. Yeniden değerlendirme: ACK'ler, yalnızca SYN'lere yanıt olarak gönderilmek yerine, bir SYN geçtikten sonra gönderilir.
The Spooniest

Bu, üçüncü mesaja neden ihtiyaç duyduğumuzu mantıklı açıklayabilecek en iyi cevap. Teşekkürler Spooniest.
Parth Patel,

7

Aslında, 3 yollu bir el sıkışma bir TCP bağlantısı kurmanın tek yolu değildir. Eşzamanlı SYN değişimine de izin verilir: http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh-4.htm

Bir çeşit çift yönlü 2 el sıkışma olarak görülebilir.


1
İyi nokta, ancak bu çok nadirdir, çünkü her iki cihazın da aynı kaynak / hedef portunu kullanması ve diğerinin de SYN'yi almadan önce her iki cihazın da bir SYN göndermesi gerekir. Oluştuğunda bile, geleneksel 3 yollu el sıkışmasının gerektirdiği üç paketten daha fazla olan dört paket gönderilmesini içerir; Nihayetinde, genel olarak daha az toplam verimlilik pahasına kurmak için biraz daha hızlı olma olasılığı (% 33 daha fazla paket iletilmesi gerekir).
YLearn

4

TCP bağlantısı çift yönlüdür. Bunun anlamı, aslında bir çift yönlü bağlantı olduğu. Başlatıcı SYN gönderir, cevaplayıcı ACK gönderir: bir tek taraflı bağlantı başlar. "Sonra" yanıtlayıcı SYN'yi gönderir, başlatıcı ACK'yı gönderir: başka bir tek taraflı bağlantı başlar. İki tek yönlü bağlantı bir çift yönlü TCP oturumu oluşturur, katılıyorum? Yani mantıksal olarak dört adım var; ancak SYN ve ACK bayrakları TCP başlığının farklı "alanları" olduğundan, eşzamanlı olarak ayarlanabilirler - ikinci ve üçüncü adımlar (dördün) birleştirilir, teknik olarak üç paket alışverişi vardır. Her bir tek yönlü (yarım) bağlantı, önerdiğiniz gibi 2 yönlü değişim kullanır.


2

Sunucu ve İstemci bir bağlantı oluşturmak istiyorsa, dört şeyi onaylamaları gerekir:

  1. Sunucunun müşteriden paket alabildiğini doğrulaması gerekiyor.
  2. Müşterinin Sunucudan paket alabildiğini doğrulaması gerekir.

  3. Müşterinin bir şeyi onaylaması gerekir: Sunucu İstemciden paket alabilir

  4. Sunucunun bir şeyi onaylaması gerekir: İstemci Sunucudan paket alabilir

Sonra Client ------SYN-----> Server, kural 1 onaylanır.

Sonra Client <---ACK/SYN---- Server, kural 2 ve 3 onaylanır.

Bu nedenle, 4. kuralı onaylamak için üçüncü bir paket gerekir.


1

Hiç gerekli değil. Kısa bir mesajın yalnızca start + mesajı içeren sunucuya bir paket, bir onay mesajı geri kabul etmesi gerektiği açıktır.

Önceki cevaplar sadece rasgele sıra numaralarına vb. İhtiyaç duyulmadan ilk önce sistemi tarif eder. Asıl soru, TCP'nin kendi tasarımıyla ilgiliydi - tabii ki TCP protokolünü kullanıyorsanız, o zaman protokol olduğu için üç mesaja ihtiyacınız var. Fakat neden TCP ilk olarak bu şekilde tasarlandı?

Bence asıl fikir, müşteriler ve sunucular arasında bir fark olmadığıydı. Her ikisi de diğerinin limanlarını iki yönlü bir şekilde biliyordu ve ikisi de sohbeti başlatabilirdi. Ve bu Syns vb gerekli.

Fakat bu, elbette, bugün nasıl kullanıldığı değildir. Sunucu bilinen bir bağlantı noktasını dinler ve "kabul eder" yapar ve istemci bağlantı noktası numarası geçicidir. Normal işletim sistemlerinde aynı müşteri port numarasından bir başkasına bir istek göndermesi için "kabul et" bekleyen bir sunucunun mümkün olduğunu bile sanmıyorum .

(Bunun, bugün hiç yapılmayan, bağlantının iki yönlü başlatılmasıyla ilgili olduğunu unutmayın. Bu, bir kez kurulan bir bağlantı üzerinden iki yönlü mesajların gönderilmesinden oldukça farklıdır.)

TCP verimsizliği etrafında çalışmak için, aynı bağlantıyı birden fazla istek için yeniden kullanabilen HTTP 1.1 gibi protokoller kullanırız ve böylece ilk başta gerekli olmayan TCP el sıkışmasından kaçınırız.

Ancak Http 1.1 nispeten yeni. Ve SSL / TLS, PKI algoritmalarının maliyeti nedeniyle, oturumu baştan yeniden kullanmanın bir yoluna ihtiyaç duyuyordu. Bu protokol, TCP'nin üstünde çalışan Http 1.1'in üzerinde çalışan kendi oturum yeniden kullanma mekanizmasını içerir.

Yazılım böyledir. Bir araya geldiğinde kabul edilebilir bir sonuç veren çamurlardaki şekerlemeler.


OSI katman-4'ün üzerindeki herhangi bir şey (örneğin, HTTP, FTP vb.) Burada açıkça açıktır. 1 - 4 arasındaki katmanlarda, istemci / sunucu diye bir şey yoktur. TCP eşler arasındaki bir bağlantıdır. Evet, üst katman protokolleri bir istemci / sunucu ilişkisi yaratıyor, ancak bu konu dışı.
Ron Maupin

1
Bu arada, HTTP TCP kullanır, bu yüzden TCP el sıkışması yine de gereklidir. Nedenini anlamak için RFC 793 İLETİM KONTROL PROTOKOLÜ'nü okuyun . HTTP gibi protokoller, uygulamanın, TCP'nin normalde uygulama için yapacağı çoklama işlemini yapmasını gerektirir.
Ron Maupin

@RonMaupin Özgün soru neden oldu? Cevap ise, uygulamada asla üst seviye katmanlar tarafından kullanılmayan bir kullanım durumunu desteklemektir. Yani, oldukça alakalı görünüyor.
Tuntable

@RonMaupin Evet, HTTP, TCP kullanır. Açıklığa kavuştum, teşekkürler. Ancak bu, TCP el sıkışmasını herhangi bir derin anlamda gerekli kılmaz.
Tuntable

1
Uygulamalar ve uygulama katmanı protokolleri açıkça burada açıklanmaktadır. @Eddie soruyu yanıtladı ve TCP RFC'yi okuyup anlarsanız, el sıkışmasının neden gerekli olduğunu anlayacaksınız. Açıkça, el sıkışma gerekmediğini, herhangi bir destek almadan iddia etmeniz için hiçbir şey eklediğini sanmıyorum.
Ron Maupin

1

Eddie'nin cevabını okuduktan sonra (doğru olarak kabul edildi), neden hala ilk sunucunun her iki ISN'yi rastgele sayılarla atayamayacağı ve ikincisi de bunu kabul edemediği sorusu vardır. 3 yönlü el sıkışma kullanmanın asıl nedeni, yarı bağlantıdan kaçınmaktır . 2 yönlü el sıkışmasında yarım bağlantı senaryosu:
1) Müşteri --- SYN -> Sunucu
2) Müşteri fikrini değiştirdi ve artık bağlanmak istemiyor
3) Müşteri <-X-ACK-- Sunucu // ACK kaybedildi
Sunucu, resent SYN'yi görmüyor, bu nedenle müşterisinin ACK'sını aldığını ve bağlantının kurulduğunu düşünüyor. Sonuç olarak, Sunucunun asla kapatılamayacak bir bağlantısı var.


Aslında, bir ana bilgisayar (istemciler ve sunucular, TCP'nin hiçbir şey bilmediği bir uygulama kavramıysa), bir ACK veya var olmayan bir bağlantıdaki herhangi bir trafik alırsa (senaryoda 3. adım), alınan segmenti görmezden gelmeyecek bir RST gönderir .
Ron Maupin

@RonMaupin Öyleyse ACK paketi kaybolduğunda durumu varsayalım.
Sanzhar Yeleuov

ACK kaybedilirse, adım 1'de başlatılan bağlantı zaman aşımına uğrar. RFC 793, diyagramlar dahil tüm senaryo türlerinin tam bir açıklamasına sahiptir.
Ron Maupin

@RonMaupin Gönderimimdeki senaryo aynı kalırsa, değişen tek şey ACK'nın kaybolduğu anlamına gelir.
Sanzhar Yeleuov

Hepsi RFC'de. Bir bağlantı açılıncaya kadar, alınan herhangi bir trafik bir RST ile sonuçlanacaktır. Üçlü el sıkışma bağlantı parametreleri üzerinde anlaşır, bu nedenle "sunucu" "istemciye" hiçbir şey geri gönderemez ancak "istemciden" bir ACK alana kadar SYN / ACK olur. Eğer "server" SYN / ACK tekrar "client" a geri dönerse, "server" tekrar deneyecektir. RFC tüm bunları açıklar.
Ron Maupin
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.