HTTP的POST请求需要TCP三次握手吗?

If you are asking in a general sense, then the answer is most definitely "yes", any HTTP method (like POST) requires a TCP connection, and the only way to initiate a TCP connection is to use the three way handshake.

IF, however, you are asking in a specific case, maybe if you are capturing your own traffic and don't see the 3 way handshake after you submit content to a website, then the answer is a little less simple. We'll have to discuss a few HTTP related concepts before we can properly answer it...


In the original release of HTTP1.0, every object you requested from a webpage required a new TCP connection to be formed for each object. Take the following simplistic website that includes some text, and two images:

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

In traditional HTTP1.0, to load this website into your browser would require three TCP connections (each with their own 3-way handshake, and 4-way closure).

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

Note there are 27 packets above, just to download three items: The HTML page itself (index.html), image a.gif, and image b.gif. (there would actually be more than 27 packets, but to save vertical space, I only included the ACK's in the 3-way-handshake and the 4-way-closure, and omitted ACK's within the data stream)

To improve the efficiency of HTTP, a feature called "Connection Keepalive" was introduced, which allows HTTP to re-use the same TCP connection to request for multiple objects. The transfer above would be reduced to the following:

HTTP 1.1 with Connection Keepalive

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

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

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

Notice that only a single TCP connection was used to request all three objects. This time, it only took 13 packets, a large improvement from the 27 from earlier.

The last imrpovement to HTTP that we must discuss is a feature called Pipelining. This feature further increased HTTP's efficiency, by making it so the Client can requests multiple options at once, without waiting to receive the prior asked object. Let me show you:

HTTP1.1 with Pipelining

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

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

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

We're still only using one TCP connection, and we're still only using 9 packets. However, we don't have to wait the Round Trip Time (RTT) it takes between the Client and the Server in between asking for and receiving each object. If you need an analogy, imagine you're at a Restaurant, and you need Salt, Pepper, and Ketchup. Is it more efficient to ask your waiter/waitress for all three items at once, or to ask for them one at a time and wait for them to come back before making the next request?

(Pipelining isn't directly related to your question, but is often described in conjunction with Keepalives and other HTTP efficiency features, so I decided to include it in this answer for completeness)


Now we can finally come back to your question:

Is a TCP three-way handshake required for an HTTP POST?

If you open a connection to a web server and download a webpage using the GET method, and that webserver supports connection keepalive. Subsequent requests to that web server, including the POST method, might simply re-use the already existing TCP connection. Therefore, that particular POST would not require a new 3-way handshake, since the data would be transferred in an already existing TCP connection.

Connection Keepalive, however, does not have an infinite duration. So if after downloading the webpage, you waited a while before sending your POST, the original TCP connection may have already closed, and in this case, your browser would have to open a new TCP connection to POST your data, which would obviously require starting with the 3-way handshake.

Since many browsers and webservers use different timers for how long they want their "connection keepalive" feature to keep connections alive, I wouldn't be able to give you reliable numbers as to how long it typically asks.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
客户端与服务器端交互的http协议数据包通常包括请求头、请求体、响应头和响应体。请求头包含了请求的方法、URI、协议版本、请求头部字段等信息;请求体包含了请求的实体内容,例如POST请求中的表单数据;响应头包含了响应的状态码、响应头部字段等信息;响应体包含了响应的实体内容。 客户端与服务器端在建立TCP连接时所交互的数据包包括SYN、SYN-ACK和ACK。第一个SYN包由客户端发出,请求建立连接;服务器端收到SYN包后,回复一个SYN-ACK包,表示已收到请求;最后客户端发出ACK包,表示收到了SYN-ACK包,TCP连接建立成功。 TCP连接成功建立之后,客户端接下来发出的TCP包中ack和seq字段的值会根据数据包的序号和确认号进行变化。seq字段表示发送方的数据包序列号,ack字段表示接收方期望接收到的数据包序列号。客户端发出的数据包中,seq字段表示已发送的数据包序列号,ack字段表示期望接收到的服务器端数据包序列号。 客户端与服务器端在释放TCP连接时所交互的数据包包括FIN、ACK和FIN-ACK。首先客户端发出FIN包,请求释放连接;服务器端收到FIN包后,回复ACK包,表示已收到请求;最后服务器端发出FIN-ACK包,表示服务器端已经准备好释放连接。释放连接比建立连接多一次交互,是因为在释放连接的过程中需要确保已经所有数据都已经传输完成,避免数据丢失。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值