Có phải bắt tay ba bước TCP cho HTTP POST không?


10

Tôi hoàn toàn không hiểu nếu tôi đăng dữ liệu biểu mẫu http từ trình duyệt lên máy chủ, giao thức vẫn cần thực hiện bắt tay ba bước (syn-ack-data) hay nó chỉ hoạt động cho các yêu cầu GET http?

Câu trả lời:


12

Cả HTTP GET và HTTP POSTS đều sử dụng TCP. Nếu bạn đang hỏi liệu POST cũng yêu cầu bắt tay TCP 3 chiều (syn-synack-ack), thì nó cũng giống như bất kỳ kết nối TCP nào khác. Bắt tay TCP là bắt buộc trước khi bất kỳ giao thức ứng dụng nào (như HTTP) bắt đầu hoạt động.

FYI, bắt tay ba chiều của bạn là không chính xác; nó phải là "syn-synack-ack"

THÊM VÀO:

Nếu trình duyệt sử dụng giao thức QUIC (Kết nối Internet UDP nhanh, phát âm nhanh. Giao thức được đề xuất bởi Google) cho HTTP có thể tránh bắt tay TCP 3 chiều. Nhưng AFAIK nó được hỗ trợ trong Chrome và Google.

Hầu hết các phần mềm thích HTTP / 2 vẫn là TCP nhưng có nhiều tính năng sử dụng kết nối liên tục sau đó bắt tay 3 bước một lần cho mỗi máy chủ.

Nếu các giao thức này được sử dụng, có thể tránh được hanshake 3 chiều theo bất kỳ yêu cầu nào, bao gồm cả GET.


24

Nếu bạn đang hỏi theo nghĩa chung, thì câu trả lời chắc chắn là "có", bất kỳ phương thức HTTP nào (như POST) đều yêu cầu kết nối TCP và cách duy nhất để bắt đầu kết nối TCP là sử dụng bắt tay ba cách.

Tuy nhiên, nếu bạn đang hỏi trong một trường hợp cụ thể, có thể nếu bạn đang nắm bắt lưu lượng truy cập của riêng mình và không thấy bắt tay 3 cách sau khi bạn gửi nội dung đến một trang web, thì câu trả lời sẽ đơn giản hơn một chút. Chúng ta sẽ phải thảo luận về một vài khái niệm liên quan đến HTTP trước khi chúng ta có thể trả lời đúng ...


Trong bản phát hành gốc của HTTP1.0, mọi đối tượng bạn yêu cầu từ một trang web đều yêu cầu kết nối TCP mới được hình thành cho từng đối tượng. Lấy trang web đơn giản sau bao gồm một số văn bản và hai hình ảnh:

<HTML>
  <HEAD>
    <TITLE>My Title</TITLE>
  </HEAD>
  <BODY>
    Stack Exchange Rules!
    <IMG SRC="a.gif">
    <IMG SRC="b.gif">
  </BODY>
</HTML>

Trong HTTP1.0 truyền thống, để tải trang web này vào trình duyệt của bạn sẽ cần ba kết nối TCP (mỗi kết nối có bắt tay 3 chiều và đóng 4 chiều).

HTTP 1.0:

--> SYN
                SYN ACK <--
--> ACK

--> GET /index.html
           <index.html> <--

--> FIN
                    ACK <--
                    FIN <--
--> ACK

.

--> SYN
                SYN ACK <--
--> ACK

--> GET /a.gif
                <a.gif> <--

--> FIN
                    ACK <--
                    FIN <--
--> ACK

.

--> SYN
                SYN ACK <--
--> ACK

--> GET /b.gif
                <b.gif> <--

--> FIN
                    ACK <--
                    FIN <--
--> ACK

Lưu ý có 27 gói ở trên, chỉ để tải xuống ba mục: Bản thân trang HTML (index.html), hình ảnh a.gif và hình ảnh b.gif. (thực sự sẽ có hơn 27 gói, nhưng để tiết kiệm không gian theo chiều dọc, tôi chỉ đưa ACK vào trong bắt tay 3 chiều và đóng 4 chiều và bỏ qua ACK trong luồng dữ liệu)

Để cải thiện hiệu quả của HTTP, một tính năng có tên "Keepalive Connection" đã được giới thiệu, cho phép HTTP sử dụng lại cùng một kết nối TCP để yêu cầu nhiều đối tượng. Việc chuyển tiền ở trên sẽ được giảm xuống như sau:

HTTP 1.1 với Keepalive kết nối

--> SYN
                SYN ACK <--
--> ACK

--> GET /index.html
           <index.html> <--
--> GET /a.gif
                <a.gif> <--
--> GET /b.gif
                <b.gif> <--

--> FIN
                    ACK <--
                    FIN <--
--> ACK

Lưu ý rằng chỉ có một kết nối TCP được sử dụng để yêu cầu cả ba đối tượng. Lần này, nó chỉ mất 13 gói, một cải tiến lớn so với 27 gói trước đó.

Sự cải thiện cuối cùng đối với HTTP mà chúng ta phải thảo luận là một tính năng có tên là Pipelining. Tính năng này tăng thêm hiệu quả của HTTP, bằng cách làm cho nó để Khách hàng có thể yêu cầu nhiều tùy chọn cùng một lúc mà không cần chờ nhận đối tượng được hỏi trước đó. Tôi se cho bạn xem:

HTTP1.1 với Pipelining

--> SYN
                SYN ACK <--
--> ACK

--> GET /index.html
--> GET /a.gif
--> GET /b.gif
           <index.html> <--
                <a.gif> <--
                <b.gif> <--

--> FIN
                    ACK <--
                    FIN <--
--> ACK

Chúng tôi vẫn chỉ sử dụng một kết nối TCP và chúng tôi vẫn chỉ sử dụng 9 gói. Tuy nhiên, chúng tôi không phải đợi Thời gian khứ hồi (RTT) giữa Máy khách và Máy chủ ở giữa yêu cầu và nhận từng đối tượng. Nếu bạn cần một sự tương tự, hãy tưởng tượng bạn đang ở một Nhà hàng và bạn cần Muối, Hạt tiêu và Ketchup. Có hiệu quả hơn không khi yêu cầu người phục vụ / phục vụ bàn của bạn cho cả ba món cùng một lúc, hoặc hỏi từng món một và đợi họ quay lại trước khi đưa ra yêu cầu tiếp theo?

(Pipelining không liên quan trực tiếp đến câu hỏi của bạn, nhưng thường được mô tả cùng với Keepalives và các tính năng hiệu quả HTTP khác, vì vậy tôi đã quyết định đưa nó vào câu trả lời này cho đầy đủ)


Bây giờ chúng tôi cuối cùng có thể trở lại câu hỏi của bạn:

Có phải bắt tay ba bước TCP cho HTTP POST không?

Nếu bạn mở một kết nối đến máy chủ web và tải xuống một trang web bằng phương thức GET và máy chủ web đó hỗ trợ duy trì kết nối. Các yêu cầu tiếp theo đến máy chủ web đó, bao gồm phương thức POST, có thể chỉ cần sử dụng lại kết nối TCP đã có. Do đó, POST cụ thể đó sẽ không yêu cầu bắt tay 3 bước mới, vì dữ liệu sẽ được truyền trong kết nối TCP hiện có.

Kết nối Keepalive, tuy nhiên, không có thời lượng vô hạn. Vì vậy, nếu sau khi tải xuống trang web, bạn đã đợi một lúc trước khi gửi POST, kết nối TCP ban đầu có thể đã bị đóng và trong trường hợp này, trình duyệt của bạn sẽ phải mở kết nối TCP mới để POST dữ liệu của bạn, điều này rõ ràng sẽ yêu cầu bắt đầu với cái bắt tay 3 chiều.

Vì nhiều trình duyệt và máy chủ web sử dụng các bộ hẹn giờ khác nhau trong bao lâu họ muốn tính năng "giữ kết nối" của họ để duy trì kết nối, tôi sẽ không thể cung cấp cho bạn các số đáng tin cậy về thời gian mà nó thường hỏi.


1
Đây là một câu trả lời đầy đủ hơn. Cảm ơn rất nhiều. Chắc chắn giá trị để được nâng cao.
Manikandan Sigamani

1
Làm thế nào về minh họa HTTP / 2: p?
animaacija

Trên thực tế, bắt tay ba chiều không phải là cách duy nhất để mở các kết nối TCP. Để đề cập đến các cách khác, ít nhất có kết nối mở và chia tay bắt tay.
juhist

1
Thế giới sẽ là một nơi tốt đẹp hơn nếu tất cả các câu trả lời sẽ được chi tiết như thế này! Làm tốt lắm, giải thích rất tốt.
dawez

Với bộ định tuyến tối ưu hóa TCP hoặc proxy, trình duyệt có thể bắt đầu gửi dữ liệu HTTP khi thấy thiết lập kết nối TCP giả từ tác nhân cục bộ khi máy chủ vẫn thiết lập kết nối với phần ngoài cùng của môi trường của máy khách. Và hãy suy nghĩ một phút nếu trình tối ưu hóa TCP chạy ở giữa hoặc trong môi trường máy chủ!
lươn ghEEz

0

Thật. Nhưng dù sao, vẫn còn một cách để làm cho nó hiệu quả hơn - dữ liệu có thể được đưa vào các gói SYN-SYNACK-ACK, mặc dù cho đến khi bắt tay xong, dữ liệu không thể được sử dụng.

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.