Mengapa kita membutuhkan jabat tangan 3 arah? Kenapa tidak hanya 2 arah?

124

Jabat tangan TCP 3 arah bekerja seperti ini:

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

Kenapa tidak begini saja?

Client ------SYN-----> Server
Client <-----ACK------ Server
smwikipedia
sumber
24
Mengapa kita bahkan membutuhkan jabat tangan? Mengapa pesan tidak dapat dikirim dengan paket pertama?
Mehrdad
4
Jika Anda ingin melewatkan jabat tangan, Anda bisa menggunakan UDP.
OzNetNerd
5
@Mehrdad, jika Anda memiliki pertanyaan Anda sendiri, silakan gunakan tautan Tanya Jawab di bagian atas halaman untuk memposting pertanyaan Anda.
YPelajari
40
@YLearn: Maaf, ini bukan pertanyaan saya sendiri, tapi itu untuk memotivasi pembaca untuk memberikan jawaban yang menggali lebih dalam dari apa yang secara harfiah dinyatakan dalam pertanyaan.
Mehrdad
3
Jangan lupa tentang TCP Fast Open (RFC 7413)
Alnitak

Jawaban:

160

Jatuhkan jabat tangan menjadi apa yang sebenarnya dilakukannya.

Dalam TCP, kedua pihak melacak apa yang telah mereka kirim dengan menggunakan nomor Urutan. Secara efektif itu berakhir dengan jumlah byte yang berjalan dari semua yang dikirim. Pihak penerima dapat menggunakan nomor urut lawan bicara untuk mengetahui apa yang telah diterimanya.

Tetapi nomor urut tidak dimulai dari 0. Ini dimulai pada ISN (Nomor Urutan Awal), yang merupakan nilai yang dipilih secara acak. Dan karena TCP adalah komunikasi dua arah, kedua belah pihak dapat "berbicara", dan karena itu keduanya harus secara acak menghasilkan ISN sebagai Nomor Urutan awal mereka. Yang pada gilirannya berarti, kedua belah pihak harus memberi tahu pihak lain tentang ISN awal mereka.

Jadi, Anda berakhir dengan urutan peristiwa ini untuk memulai percakapan TCP antara Alice dan Bob:

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]

Perhatikan, empat peristiwa terjadi:

  1. Alice mengambil ISN dan Menyinkronkannya dengan Bob.
  2. Bob ACKnowledges the ISN.
  3. Bob mengambil ISN dan Menyinkronkannya dengan Alice.
  4. Alice ACKnowledges the ISN.

Pada kenyataannya, dua peristiwa tengah (# 2 dan # 3) terjadi dalam paket yang sama. Apa yang membuat paket a SYNatau ACKhanya flag biner dihidupkan atau dimatikan di dalam setiap header TCP , jadi tidak ada yang mencegah kedua flag ini diaktifkan pada paket yang sama. Jadi jabat tangan tiga arah akhirnya menjadi:

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

Perhatikan dua contoh "SYN" dan "ACK", masing-masing, di kedua arah.


Jadi untuk kembali ke pertanyaan Anda, mengapa tidak menggunakan jabat tangan dua arah? Jawaban singkatnya adalah karena jabat tangan dua arah hanya akan memungkinkan satu pihak untuk membangun ISN, dan pihak lain untuk mengakuinya. Yang berarti hanya satu pihak yang dapat mengirim data.

Tetapi TCP adalah protokol komunikasi dua arah, yang berarti kedua ujung harus dapat mengirim data dengan andal. Kedua belah pihak perlu membuat ISN, dan kedua belah pihak harus mengakui ISN yang lain.

Jadi sebenarnya, apa yang Anda miliki adalah persis deskripsi Anda tentang jabat tangan dua arah, tetapi di setiap arah . Makanya, empat peristiwa terjadi. Dan lagi, dua flag tengah terjadi dalam paket yang sama. Oleh karena itu, tiga paket terlibat dalam proses inisiasi koneksi TCP penuh.

Eddie
sumber
6
Mengapa kita membutuhkan ISN sama sekali? Manusia tidak membutuhkannya, mengapa komputer? Apakah ada buktinya, atau kita hanya memilikinya karena nyaman?
Mehrdad
19
@Mehrdad: Anda perlu nomor urut agar transmisi ulang berfungsi dengan benar (atau memang sama sekali). ISN tidak bisa hanya menjadi nol karena serangan prediksi urutan .
Kevin
4
@Mehrdad Ruang obrolan tidak harus berupa 'waktu nyata', kita dapat meninggalkan pesan untuk satu sama lain. Alasan saya berpikir untuk mengarahkannya ke tempat lain adalah karena Anda sekarang mengajukan pertanyaan yang berbeda. OP bertanya "mengapa itu jabat tangan 3 arah, bukan 2", tapi sekarang Anda mempertanyakan "mengapa kita perlu nomor Urutan sama sekali", yang berbeda. Daripada menggagalkan utas ini, saya pikir kita harus membahas pertanyaan lain dalam obrolan. Atau , Anda dapat memposting pertanyaan baru, saya yakin itu akan memberikan jawaban yang bagus.
Eddie
4
Hebat, jawaban singkat. Membaca "ACK SYN" secara fundamental terasa salah tetapi Anda bahkan menjelaskan itu +1.
Lilienthal
3
Menurut RFC 793, Transmission Control Protocol : " Alasan utama untuk jabat tangan tiga arah adalah untuk mencegah inisiasi koneksi duplikat yang lama dari menyebabkan kebingungan. "
Ron Maupin
23

Tiga-way handshake diperlukan karena kedua belah pihak perlu syn chronize nomor urut segmen mereka digunakan selama transmisi mereka. Untuk ini, masing-masing mengirimkan (pada gilirannya) segmen SYN dengan nomor urut diatur ke nilai acak n , yang kemudian ack nowledged oleh pihak lain melalui segmen ACK dengan nomor urut set ke n + 1 .

dr01
sumber
Mengapa pengakuan itu dibutuhkan?
Paŭlo Ebermann
4
@ PaŭloEbermann: Karena jika tidak, Server tidak tahu apakah klien pernah menerima SYN, dan penting bahwa klien menerima itu.
Mooing Duck
2
@ PaŭloEbermann Dan untuk membuktikannya, langkah ACK adalah mengakui dengan [X + 1]. - dikutip dari Eddiekomentar untuk jawabannya.
smwikipedia
14

Agar koneksi berfungsi, masing-masing pihak perlu memverifikasi bahwa itu dapat mengirim paket ke sisi lain. Satu-satunya cara untuk memastikan bahwa Anda mendapat paket ke pihak lain adalah dengan mendapatkan paket dari mereka yang, menurut definisi, tidak akan dikirim kecuali paket yang Anda kirim melewati . TCP pada dasarnya menggunakan dua jenis pesan untuk ini: SYN (untuk meminta bukti bahwa paket ini berhasil melewati) dan ACK (yang hanya akan dikirim setelah SYN berhasil, untuk membuktikan bahwa SYN berhasil). Sebenarnya ada jenis pesan ketiga, tapi kita akan membahasnya sebentar lagi.

Sebelum koneksi dimulai, tidak ada pihak yang benar-benar tahu tentang yang lain. Klien mengirim paket SYN ke server, untuk meminta bukti bahwa pesannya dapat diterima . Itu tidak memberi tahu siapa pun tentang apa pun, tetapi itu adalah langkah pertama dari jabat tangan.

Jika SYN berhasil, maka server tahu bahwa klien dapat mengirim paket ke sana, karena, yah, itu baru saja terjadi. Tetapi itu tidak membuktikan bahwa server dapat mengirim kembali paket: klien dapat mengirim SYN karena banyak alasan . Jadi server perlu mengirim dua pesan kembali ke klien: ACK (untuk membuktikan bahwa SYN berhasil) dan SYN (untuk meminta ACK sendiri). TCP menggabungkan dua pesan ini menjadi satu pesan-SYN-ACK, jika Anda mau- untuk mengurangi lalu lintas jaringan. Ini adalah langkah kedua jabat tangan.

Karena SYN-ACK adalah ACK, klien sekarang tahu pasti bahwa ia dapat mengirim paket ke server. Dan karena SYN-ACK adalah SYN, ia juga tahu bahwa server ingin bukti bahwa pesan ini berhasil. Jadi ia mengirimkan kembali ACK: hanya ACK biasa kali ini, karena tidak perlu bukti lagi bahwa paket-paketnya dapat melewati. Ini adalah langkah terakhir dari jabat tangan: klien sekarang tahu bahwa paket dapat berjalan dua arah, dan bahwa server baru saja akan mencari tahu hal ini (karena ia tahu ACK akan melaluinya).

Setelah ACK melewati, sekarang server tahu bahwa ia dapat mengirim paket ke klien . Ia juga tahu bahwa klien mengetahui hal ini, sehingga dapat mulai mengirim data segera. Jabat tangan selesai. Kami memiliki saluran yang bagus.

Sebenarnya, kita tidak dapat memastikan bahwa kita memiliki saluran yang baik . Hanya karena urutan paket yang dilewati ini tidak sepenuhnya menjamin bahwa orang lain akan melakukannya. Kami tidak dapat membuktikan bahwa tanpa mengirim SYN dan ACK dalam jumlah tak terbatas, maka tidak ada lagi yang bisa dilakukan, jadi itu bukan pilihan praktis. Namun dalam praktiknya, tiga langkah ternyata cukup baik untuk sebagian besar tujuan .

Spooniest
sumber
Ini tidak benar: "ACK (yang hanya dikirim sebagai tanggapan terhadap SYN, dan dengan demikian membuktikan bahwa SYN berhasil melewatinya)." Hanya paket pertama yang dikirim dari setiap ujung yang memiliki set flag SYN, dan semua paket selain paket pertama dari jabat tangan 3-arah memiliki set flag ACK. Paket pertama tidak dapat ACK karena pihak kedua belum SYNed, tetapi setiap paket setelah yang pertama harus ACK apa pun yang telah diterima dari ujung yang lain, apakah ada data yang dikirim kembali atau tidak.
Monty Harder
Terima kasih. Penulisan Ulang: ACK dapat dikirim setelah SYN melewati, daripada hanya dikirim sebagai tanggapan terhadap SYN.
The Spooniest
Ini adalah jawaban terbaik yang bisa menjelaskan secara logis mengapa kita membutuhkan pesan ketiga. Terima kasih, Spooniest.
Parth Patel
7

Sebenarnya, jabat tangan 3 arah bukan satu-satunya cara untuk membangun koneksi TCP. Pertukaran SYN simultan juga diperbolehkan: http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh-4.htm

Itu bisa dilihat sebagai semacam jabat tangan 2 arah ganda.

Lexelby
sumber
1
Poin bagus, namun ini sangat jarang karena kedua perangkat harus menggunakan port sumber / tujuan yang sama dan kedua perangkat harus mengirim SYN sebelum yang lain menerima SYN. Bahkan ketika hal itu terjadi, itu melibatkan empat paket yang dikirim, yang lebih dari tiga paket yang dibutuhkan oleh jabat tangan 3-arah tradisional; pada akhirnya hanya kemungkinan menjadi sedikit lebih cepat untuk diatur dalam hal waktu keseluruhan dengan biaya efisiensi keseluruhan yang kurang (membutuhkan 33% lebih banyak paket yang akan dikirim).
YPelajari
4

Koneksi TCP adalah dua arah. Apakah ini berarti bahwa itu sebenarnya adalah sepasang koneksi satu arah. Inisiator mengirim SYN, responden mengirim ACK: satu koneksi simpleks dimulai. "Lalu" responden mengirim SYN, inisiator mengirimkan ACK: koneksi simpleks lain dimulai. Dua koneksi simpleks membentuk satu sesi TCP dupleks, setuju? Jadi secara logis ada empat langkah yang terlibat; tetapi karena bendera SYN dan ACK berbeda "bidang" dari header TCP, mereka dapat diatur secara bersamaan - langkah kedua dan ketiga (dari empat) digabungkan, jadi secara teknis ada tiga paket pertukaran. Setiap koneksi simpleks (setengah) menggunakan pertukaran 2 arah, seperti yang Anda usulkan.

Sergio
sumber
2

Jika Server dan Klien ingin membuat koneksi, mereka perlu mengkonfirmasi empat hal:

  1. Server perlu mengkonfirmasi bahwa ia dapat menerima paket dari Klien
  2. Klien perlu mengkonfirmasi bahwa ia dapat menerima paket dari Server

  3. Klien perlu mengkonfirmasi sesuatu: Server dapat menerima paket dari Klien

  4. Server perlu mengkonfirmasi sesuatu: Klien dapat menerima paket dari Server

Setelah itu Client ------SYN-----> Server, aturan 1 dikonfirmasi.

Setelah Client <---ACK/SYN---- Server, aturan 2 dan 3 dikonfirmasi.

Jadi, perlu paket ketiga untuk mengonfirmasi aturan 4.

codeman-cs adalah id github saya
sumber
1

Tidak perlu sama sekali. Jelas bahwa pesan singkat hanya memerlukan satu paket ke server yang mencakup pesan awal +, dan satu paket kembali mengakuinya.

Jawaban sebelumnya hanya menggambarkan sistem tanpa mendiskusikan kebutuhan untuk nomor urut acak dll. Di tempat pertama. Pertanyaan aslinya adalah tentang desain TCP itu sendiri - jelas jika Anda menggunakan protokol TCP maka Anda memerlukan tiga pesan karena itu adalah protokol. Tetapi mengapa TCP dirancang seperti itu pada awalnya?

Saya percaya ide awalnya adalah bahwa tidak ada perbedaan antara klien dan server. Keduanya tahu port yang lain dalam dua arah, dan keduanya bisa memulai percakapan. Dan itu membutuhkan Syns dll.

Tapi ini bukan, tentu saja, bagaimana ini digunakan hari ini. Server mendengarkan pada port yang terkenal dan melakukan dan "menerima", nomor port klien bersifat sementara. Saya bahkan tidak berpikir itu mungkin untuk server menunggu "menerima" untuk mengirim permintaan ke yang lain pada nomor port klien yang sama dalam sistem operasi normal.

(Perhatikan bahwa ini adalah tentang inisiasi dua arah koneksi, yang tidak pernah dilakukan hari ini. Itu sangat berbeda dengan mengirim pesan dua arah ke koneksi yang pernah dibuat.)

Untuk mengatasi inefisiensi TCP, kami menggunakan protokol seperti HTTP 1.1 yang dapat menggunakan kembali koneksi yang sama untuk beberapa permintaan, dan dengan demikian menghindari jabat tangan TCP yang tidak diperlukan di tempat pertama.

Tapi Http 1.1 relatif baru. Dan SSL / TLS membutuhkan cara untuk menggunakan kembali sesi dari awal karena biaya algoritma PKI. Jadi protokol itu termasuk mekanisme penggunaan kembali sesi sendiri yang berjalan di atas Http 1.1 yang berjalan di atas TCP.

Begitulah cara dengan perangkat lunak. Fudges pada kludges yang bila digabungkan, menghasilkan hasil yang dapat diterima.

Tuntable
sumber
Apa pun di atas OSI layer-4 (misalnya HTTP, FTP, dll.) Secara eksplisit di luar topik di sini. Pada layer 1 hingga 4, tidak ada yang namanya client / server. TCP adalah koneksi antar rekan. Ya, protokol lapisan atas membuat hubungan klien / server, tapi itu di luar topik di sini.
Ron Maupin
1
Ngomong-ngomong, HTTP menggunakan TCP, jadi jabat tangan TCP masih diperlukan. Baca RFC 793 PROTOKOL PENGENDALIAN TRANSMISI untuk memahami mengapa. Protokol seperti HTTP memerlukan aplikasi untuk melakukan multiplexing yang biasanya dilakukan TCP untuk aplikasi tersebut.
Ron Maupin
@RonMaupin Pertanyaan awal adalah mengapa? Dan jawabannya adalah untuk mendukung use case yang tidak pernah digunakan oleh lapisan tingkat atas dalam praktiknya. Jadi, sepertinya cukup relevan.
Tuntable
@RonMaupin Ya, HTTP menggunakan TCP. Yang telah saya perjelas, terima kasih. Tapi itu tidak membuat jabat tangan TCP diperlukan dalam arti yang mendalam.
Tuntable
1
Aplikasi dan protokol lapisan aplikasi secara eksplisit di luar topik di sini. @ Eddie menjawab pertanyaan itu, dan jika Anda membaca dan memahami TCP RFC, Anda akan mengerti mengapa jabat tangan itu diperlukan. Saya tidak berpikir itu menambah apa pun bagi Anda untuk mengklaim, tanpa dukungan apa pun, bahwa berjabat tangan itu tidak perlu, padahal sudah jelas.
Ron Maupin
1

Setelah membaca jawaban Eddie (diterima sebagai benar), masih ada pertanyaan mengapa tuan rumah 1 tidak dapat menetapkan kedua ISN dengan angka acak dan 2 hanya menerimanya. Alasan sebenarnya menggunakan jabat tangan 3 arah adalah untuk menghindari setengah koneksi . Skenario koneksi setengah dalam jabat tangan 2 arah:
1) Klien --- SYN -> Server
2) Klien berubah pikiran dan tidak ingin terhubung lagi
3) Klien <-X-ACK-- Server // ACK hilang
Server tidak melihat membenci SYN, jadi dia berpikir bahwa klien mendapatkan ACK dan koneksi dibuat. Akibatnya Server memiliki koneksi yang tidak akan pernah ditutup

Sanzhar Yeleuov
sumber
Sebenarnya, jika sebuah host (klien dan server adalah konsep aplikasi yang tidak diketahui oleh TCP) menerima ACK atau lalu lintas apa pun pada koneksi yang tidak ada (langkah 3 dalam skenario Anda), ia akan mengirim RST, tidak mengabaikan segmen yang diterima .
Ron Maupin
@RonMaupin Kalau begitu mari kita asumsikan situasi ketika paket ACK hilang.
Sanzhar Yeleuov
Jika ACK hilang, maka koneksi yang dimulai pada langkah 1 akan habis. RFC 793 memiliki penjelasan lengkap tentang semua jenis skenario, termasuk diagram.
Ron Maupin
@RonMaupin Maksud saya jika skenario dari posting saya tetap sama, hanya hal yang berubah, bahwa ACK hilang.
Sanzhar Yeleuov
Semuanya ada di RFC. Sampai koneksi terbuka, lalu lintas apa pun yang diterima akan menghasilkan RST. Jabat tangan tiga arah menegosiasikan parameter koneksi, sehingga "server" tidak dapat mengirim apa pun kembali ke "klien" tetapi itu SYN / ACK sampai menerima ACK dari "klien". Jika "server" SYN / ACK kembali ke "klien" hilang, "server" akan mencoba lagi. RFC menjelaskan semua ini.
Ron Maupin