Tại sao chúng ta cần bắt tay 3 bước? Tại sao không chỉ là 2 chiều?


124

Bắt tay 3 bước TCP hoạt động như thế này:

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

Tại sao không chỉ này?

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

24
Tại sao chúng ta thậm chí cần một cái bắt tay? Tại sao tin nhắn không thể được gửi với gói đầu tiên?
Mehrdad

4
Nếu bạn muốn bỏ qua cái bắt tay, bạn có thể sử dụng UDP thay thế.
OzNetNerd

5
@Mehrdad, nếu bạn có câu hỏi của riêng mình, vui lòng sử dụng liên kết Hỏi Câu hỏi ở đầu trang để đăng bài của riêng bạn.
YLearn

40
@YLearn: Xin lỗi, đây không thực sự là một câu hỏi của riêng tôi, mà là để thúc đẩy người đọc đưa ra câu trả lời sâu hơn một chút so với những gì được nêu trong câu hỏi.
Mehrdad

3
Đừng quên về TCP Fast Open (RFC 7413)
Alnitak

Câu trả lời:


160

Phá vỡ cái bắt tay vào những gì nó đang thực sự làm.

Trong TCP, hai bên theo dõi những gì họ đã gửi bằng cách sử dụng số thứ tự. Thực tế, nó kết thúc là số byte đang chạy của mọi thứ được gửi. Bên nhận có thể sử dụng số thứ tự của người nói ngược lại để xác nhận những gì họ đã nhận được.

Nhưng số thứ tự không bắt đầu từ 0. Nó bắt đầu từ ISN (Số thứ tự ban đầu), là giá trị được chọn ngẫu nhiên. Và vì TCP là giao tiếp hai chiều, cả hai bên có thể "nói" và do đó cả hai phải tạo ngẫu nhiên một ISN làm Số thứ tự bắt đầu. Điều đó có nghĩa là, cả hai bên cần thông báo cho bên kia về ISN bắt đầu của mình.

Vì vậy, bạn kết thúc với chuỗi sự kiện này để bắt đầu cuộc trò chuyện TCP giữa Alice và 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]

Lưu ý, bốn sự kiện đang xảy ra:

  1. Alice chọn một ISN và đồng bộ hóa nó với Bob.
  2. Bob ACKnowledges ISN.
  3. Bob chọn ISN và đồng bộ hóa nó với Alice.
  4. Alice ACKnowledges ISN.

Trong thực tế, hai sự kiện giữa (# 2 và # 3) xảy ra trong cùng một gói. Điều gì làm cho gói SYNtrở thành hoặc ACKchỉ đơn giản là cờ nhị phân được bật hoặc tắt bên trong mỗi tiêu đề TCP , vì vậy không có gì ngăn cả hai cờ này được bật trên cùng một gói. Vì vậy, bắt tay ba cách kết thúc là:

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

Lưu ý hai trường hợp "SYN" và "ACK", một trong hai trường hợp, theo cả hai hướng.


Vì vậy, để trở lại câu hỏi của bạn, tại sao không sử dụng một cái bắt tay hai chiều? Câu trả lời ngắn gọn là bởi vì bắt tay hai chiều sẽ chỉ cho phép một bên thành lập ISN và bên kia thừa nhận điều đó. Có nghĩa là chỉ một bên có thể gửi dữ liệu.

Nhưng TCP là một giao thức truyền thông hai chiều, có nghĩa là đầu cuối phải có khả năng gửi dữ liệu một cách đáng tin cậy. Cả hai bên cần thành lập ISN và cả hai bên cần phải thừa nhận ISN của bên kia.

Vì vậy, trong thực tế, những gì bạn có chính xác là mô tả của bạn về bắt tay hai chiều, nhưng theo từng hướng . Do đó, bốn sự kiện xảy ra. Và một lần nữa, hai lá cờ ở giữa xảy ra trong cùng một gói. Vì ba gói như vậy có liên quan đến một quá trình khởi tạo kết nối TCP đầy đủ.


6
Tại sao chúng ta cần ISN? Con người không cần nó, tại sao máy tính? Có bằng chứng về điều này, hoặc chúng ta chỉ có chúng bởi vì chúng thuận tiện?
Mehrdad

19
@Mehrdad: Bạn cần số thứ tự để truyền lại hoạt động chính xác (hoặc thực sự là tất cả). ISN không thể bằng không vì các cuộc tấn công dự đoán theo trình tự .
Kevin

4
@Mehrdad Phòng trò chuyện không nhất thiết phải là 'thời gian thực', chúng tôi có thể để lại tin nhắn cho nhau. Lý do tôi nghĩ để hướng nó đi nơi khác là vì bây giờ bạn đang hỏi một câu hỏi khác. OP đã hỏi "tại sao lại là bắt tay 3 cách thay vì 2", nhưng bây giờ bạn đặt câu hỏi "tại sao chúng ta lại cần số thứ tự", điều này khác. Thay vì làm hỏng chủ đề này, tôi nghĩ chúng ta nên thảo luận về câu hỏi khác trong trò chuyện. Ngoài ra , bạn có thể đăng một câu hỏi mới, tôi chắc chắn rằng nó sẽ có một số câu trả lời hay.
Eddie

4
Tuyệt vời, câu trả lời súc tích. Đọc "ACK SYN" cảm thấy sai về cơ bản nhưng bạn thậm chí đã giải thích rằng +1.
Lilienthal

3
Theo RFC 793, Giao thức điều khiển truyền dẫn : " Lý do chính cho việc bắt tay ba chiều là để ngăn chặn các khởi tạo kết nối trùng lặp cũ gây nhầm lẫn. "
Ron Maupin

23

Bắt tay ba chiều là cần thiết bởi vì cả hai bên cần phải đồng bộ hóa số thứ tự phân đoạn được sử dụng trong quá trình truyền của họ. Đối với điều này, mỗi người trong số họ sẽ gửi (lần lượt) một đoạn SYN với một số thứ tự thiết lập một giá trị ngẫu nhiên n , mà sau đó được ack nowledged do bên kia thông qua một phân khúc ACK với một số thứ tự thiết lập để n + 1 .


Tại sao sự thừa nhận cần thiết?
Paulo Ebermann

4
@ PaŭloEbermann: Bởi vì nếu không thì Máy chủ không biết khách hàng có nhận được SYN hay không và điều quan trọng là khách hàng nhận được điều đó.
Vịt Mooing

2
@ PaŭloEbermann Và để chứng minh điều đó, bước ACK là xác nhận với [X + 1]. - trích dẫn từ Eddiebình luận của câu trả lời của mình.
smwikipedia

14

Để kết nối hoạt động, mỗi bên cần xác minh rằng nó có thể gửi các gói đến phía bên kia. Cách duy nhất để chắc chắn rằng bạn đã nhận được một gói ở phía bên kia là nhận một gói từ họ, theo định nghĩa, sẽ không được gửi trừ khi gói bạn gửi đi qua . TCP về cơ bản sử dụng hai loại thông báo cho việc này: SYN (để yêu cầu bằng chứng chứng minh rằng gói này đã thông qua) và ACK (chỉ được gửi sau khi một SYN được thông qua, để chứng minh rằng SYN đã thông qua). Thực sự có một loại tin nhắn thứ ba, nhưng chúng ta sẽ đến đó ngay lập tức.

Trước khi kết nối bắt đầu, không bên nào thực sự biết bất cứ điều gì về bên kia. Máy khách gửi một gói SYN đến máy chủ, để yêu cầu bằng chứng rằng các thông điệp của nó có thể vượt qua . Điều đó không nói cho bất cứ ai bất cứ điều gì, nhưng đó là bước đầu tiên của cái bắt tay.

Nếu SYN thông qua, thì máy chủ biết rằng máy khách có thể gửi các gói đến nó, bởi vì, tốt, nó vừa xảy ra. Nhưng điều đó không chứng minh rằng máy chủ có thể gửi lại các gói: khách hàng có thể gửi SYN vì nhiều lý do . Vì vậy, máy chủ cần gửi lại hai tin nhắn cho khách hàng: một ACK (để chứng minh rằng SYN đã thông qua) và một SYN (để yêu cầu một ACK của chính nó). TCP kết hợp hai tin nhắn này thành một tin nhắn SYN-ACK, nếu bạn sẽ - để giảm lưu lượng mạng. Đây là bước thứ hai của cái bắt tay.

Vì một SYN-ACK là một ACK, giờ đây khách hàng biết chắc chắn rằng nó có thể gửi các gói đến máy chủ. Và bởi vì một SYN-ACK là một SYN, nó cũng biết rằng máy chủ muốn có bằng chứng rằng thông điệp này đã được thông qua. Vì vậy, nó sẽ gửi lại một ACK: chỉ là một ACK đơn giản, bởi vì nó không cần bằng chứng nữa rằng các gói của nó có thể vượt qua. Đây là bước cuối cùng của cái bắt tay: bây giờ khách hàng biết rằng các gói có thể đi cả hai chiều và máy chủ sắp sửa tìm ra điều này (vì nó biết ACK sẽ đi qua).

Khi ACK được thông qua, bây giờ máy chủ biết rằng nó có thể gửi các gói đến máy khách . Nó cũng biết rằng khách hàng biết điều này, vì vậy nó có thể bắt đầu gửi dữ liệu ngay lập tức. Cái bắt tay đã hoàn thành. Chúng tôi có một kênh tốt.

Vâng, nói đúng ra, chúng ta không thể chắc chắn mình có một kênh tốt . Chỉ vì chuỗi các gói đã đi qua không đảm bảo nghiêm ngặt rằng những người khác sẽ làm. Chúng tôi không thể chứng minh rằng không gửi vô số SYN và ACK, và sau đó không có gì khác có thể được thực hiện, vì vậy đó không thực sự là một lựa chọn thực tế. Nhưng trong thực tế, ba bước hóa ra là đủ tốt cho hầu hết các mục đích .


Điều này là sai sự thật: "một ACK (chỉ được gửi để phản hồi lại các SYN, và do đó chứng minh rằng SYN đã thông qua)." Chỉ gói đầu tiên được gửi từ mỗi đầu có bộ cờ SYN và tất cả các gói không phải là gói đầu tiên của bắt tay 3 chiều đều có bộ cờ ACK. Gói đầu tiên không thể ACK vì bên thứ hai chưa được sao chép, nhưng mọi gói sau gói thứ nhất phải ACK bất cứ thứ gì đã nhận được từ đầu bên kia, cho dù có dữ liệu nào được gửi lại hay không.
Monty Harder

Cảm ơn. Viết lại: ACK được gửi sau khi một SYN được thông qua, thay vì chỉ được gửi để phản hồi lại các SYN.
Chiếc thìa ngon nhất

Đây là câu trả lời tốt nhất có thể giải thích một cách logic tại sao chúng ta thậm chí cần thông điệp thứ ba. Cảm ơn, Spooniest.
Parth Patel

7

Trên thực tế, bắt tay 3 chiều không phải là phương tiện duy nhất để thiết lập kết nối TCP. Trao đổi đồng thời SYN cũng được cho phép: http://www.tcpipguide.com/free/t_TCPConnectionEst Thiết lậpProcessTheThreeWayHandsh-4.htm

Đó có thể được coi là một kiểu bắt tay 2 chiều.


1
Điểm hay, tuy nhiên điều này rất hiếm khi cả hai thiết bị sẽ phải sử dụng cùng một cổng nguồn / đích và cả hai thiết bị sẽ cần phải gửi một SYN trước khi thiết bị kia nhận được SYN. Ngay cả khi nó xảy ra, nó liên quan đến bốn gói được gửi, nhiều hơn ba gói theo yêu cầu bắt tay 3 chiều truyền thống; cuối cùng chỉ có khả năng thiết lập nhanh hơn một chút về mặt thời gian với chi phí hiệu quả tổng thể thấp hơn (yêu cầu truyền thêm 33% gói tin).
YLearn

4

Kết nối TCP là hai chiều. Điều này có nghĩa là nó thực sự là một cặp kết nối một chiều. Bộ khởi tạo gửi SYN, bộ trả lời gửi ACK: một kết nối đơn giản bắt đầu. "Sau đó" bộ trả lời gửi SYN, bộ khởi tạo gửi ACK: một kết nối đơn giản khác bắt đầu. Hai kết nối đơn giản tạo thành một phiên TCP song công, đồng ý? Vì vậy, logic có bốn bước liên quan; nhưng vì các cờ SYN và ACK là các "trường" khác nhau của tiêu đề TCP, nên chúng có thể được đặt đồng thời - bước thứ hai và thứ ba (của bốn) được kết hợp, do đó về mặt kỹ thuật có ba trao đổi gói. Mỗi kết nối đơn giản (một nửa) sử dụng trao đổi 2 chiều, như bạn đề xuất.


2

Nếu Máy chủ và Máy khách muốn tạo kết nối, họ cần xác nhận bốn điều:

  1. Máy chủ cần xác nhận anh ta có thể nhận gói tin từ Máy khách
  2. Khách hàng cần xác nhận rằng anh ta có thể nhận gói tin từ Máy chủ

  3. Khách hàng cần xác nhận một điều: Máy chủ có thể nhận gói từ Máy khách

  4. Máy chủ cần xác nhận một điều: Máy khách có thể nhận gói từ Máy chủ

Sau đó Client ------SYN-----> Server, quy tắc 1 được xác nhận.

Sau đó Client <---ACK/SYN---- Server, quy tắc 2 và 3 được xác nhận.

Vì vậy, cần một gói thứ ba để xác nhận quy tắc 4.


1

Nó không cần thiết chút nào. Rõ ràng là một tin nhắn ngắn chỉ nên yêu cầu một gói đến máy chủ bao gồm thông điệp start + và một gói trở lại thừa nhận nó.

Các câu trả lời trước chỉ mô tả hệ thống mà không thảo luận về sự cần thiết của số thứ tự ngẫu nhiên, vv ở vị trí đầu tiên. Câu hỏi ban đầu là về thiết kế của chính TCP - rõ ràng nếu bạn sử dụng giao thức TCP thì bạn cần ba thông báo vì đó là giao thức. Nhưng tại sao TCP được thiết kế theo cách đó ngay từ đầu?

Tôi tin rằng ý tưởng ban đầu là không có sự phân biệt giữa máy khách và máy chủ. Cả hai đều biết các cổng của nhau theo cách hai chiều và có thể bắt đầu cuộc trò chuyện. Và điều đó yêu cầu Syns, v.v.

Nhưng tất nhiên đây không phải là cách sử dụng ngày nay. Máy chủ lắng nghe trên một cổng nổi tiếng và thực hiện và "chấp nhận", số cổng máy khách là phù du. Tôi thậm chí không nghĩ rằng một máy chủ đang chờ "chấp nhận" có thể gửi yêu cầu đến người khác trên cùng một số cổng khách trong các hệ điều hành bình thường.

(Lưu ý rằng đây là về việc bắt đầu hai chiều của kết nối, điều này chưa bao giờ được thực hiện ngày hôm nay. Điều này hoàn toàn khác với việc gửi tin nhắn hai chiều xuống một kết nối sau khi được thiết lập.)

Để khắc phục sự kém hiệu quả của TCP, chúng tôi sử dụng các giao thức như HTTP 1.1 có thể sử dụng lại cùng một kết nối cho nhiều yêu cầu và do đó tránh bắt tay TCP không cần thiết ở nơi đầu tiên.

Nhưng http 1.1 tương đối mới. Và SSL / TLS cần một cách để sử dụng lại phiên ngay từ đầu do chi phí của các thuật toán PKI. Vì vậy, giao thức đó bao gồm cơ chế tái sử dụng phiên riêng của nó chạy trên đỉnh 1.1 1.1 chạy trên TCP.

Đó là cách với phần mềm. Fudges trên bùn mà khi kết hợp, tạo ra một kết quả chấp nhận được.


Bất cứ điều gì ở trên OSI lớp 4 (ví dụ HTTP, FTP, v.v.) rõ ràng không có chủ đề ở đây. Trong các lớp 1 đến 4, không có thứ gọi là máy khách / máy chủ. TCP là một kết nối giữa các đồng nghiệp. Có, các giao thức lớp trên tạo mối quan hệ máy khách / máy chủ, nhưng đó là ngoài chủ đề ở đây.
Ron Maupin

1
Nhân tiện, HTTP sử dụng TCP, do đó bắt tay TCP vẫn là cần thiết. Đọc ROT 793 PROTOCOL KIỂM SOÁT TRUYỀN THÔNG để hủy bỏ lý do tại sao. Các giao thức như HTTP yêu cầu ứng dụng thực hiện ghép kênh mà TCP thường làm cho ứng dụng.
Ron Maupin

@RonMaupin Câu hỏi ban đầu là tại sao? Và câu trả lời là hỗ trợ một trường hợp sử dụng không bao giờ được sử dụng bởi các lớp cấp trên trong thực tế. Vì vậy, có vẻ khá liên quan.
Tuntable

@RonMaupin Có, HTTP sử dụng TCP. Mà tôi đã làm rõ, cảm ơn. Nhưng điều đó không làm cho việc bắt tay TCP trở nên cần thiết theo bất kỳ ý nghĩa sâu sắc nào.
Tuntable

1
Các ứng dụng và giao thức lớp ứng dụng rõ ràng lạc đề ở đây. @Eddie đã trả lời câu hỏi và nếu bạn đọc và hiểu TCP RFC, bạn sẽ hiểu lý do tại sao bắt tay là cần thiết. Tôi không nghĩ rằng nó bổ sung bất cứ điều gì để bạn yêu cầu, mà không cần bất kỳ sự hỗ trợ nào, rằng cái bắt tay là không cần thiết, khi nó rõ ràng là như vậy.
Ron Maupin

1

Sau khi đọc câu trả lời của Eddie (được chấp nhận là chính xác), vẫn còn câu hỏi tại sao máy chủ thứ 1 không thể gán cả ISN với số ngẫu nhiên và thứ 2 chỉ chấp nhận nó. Lý do thực sự của việc sử dụng bắt tay 3 chiều là để tránh một nửa kết nối . Kịch bản kết nối một nửa trong bắt tay 2 chiều:
1) Máy khách --- SYN -> Máy chủ
2) Máy khách thay đổi ý định và không muốn kết nối nữa
3) Máy khách <-X-ACK-- Máy chủ // ACK bị mất
Máy chủ không thấy SYN bực bội, vì vậy anh ta nghĩ rằng khách hàng đã nhận được ACK của mình và kết nối được thiết lập. Kết quả là Máy chủ có kết nối sẽ không bao giờ bị đóng


Trên thực tế, nếu máy chủ (máy khách và máy chủ là khái niệm ứng dụng mà TCP không biết gì) sẽ nhận được ACK hoặc bất kỳ lưu lượng truy cập nào trên kết nối không tồn tại (bước 3 trong kịch bản của bạn), nó sẽ gửi RST, không bỏ qua phân đoạn nhận được .
Ron Maupin

@RonMaupin Sau đó, hãy giả sử tình huống khi gói ACK bị mất.
Sanzhar Yeleuov

Nếu ACK bị mất, thì kết nối được bắt đầu ở bước 1 sẽ hết thời gian. RFC 793 có một lời giải thích đầy đủ về tất cả các loại kịch bản, bao gồm cả sơ đồ.
Ron Maupin

@RonMaupin Ý tôi là nếu kịch bản từ bài viết của tôi vẫn giữ nguyên, chỉ có điều thay đổi, ACK đó đã bị mất.
Sanzhar Yeleuov

Đó là tất cả trong RFC. Cho đến khi một kết nối được mở, bất kỳ lưu lượng truy cập nhận được sẽ dẫn đến RST. Cái bắt tay ba chiều đàm phán các tham số kết nối, vì vậy "máy chủ" không thể gửi lại bất cứ thứ gì cho "máy khách" nhưng đó là SYN / ACK cho đến khi nhận được ACK từ "máy khách". Nếu "máy chủ" SYN / ACK trở lại "máy khách" bị mất, "máy chủ" sẽ thử lại. RFC giải thích tất cả điều này.
Ron Maupin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.