我不太明白我是否将 http 表单数据从浏览器发布到服务器,该协议是否仍然需要进行三向握手(syn-ack-data)还是仅适用于 GET http 请求?
HTTP POST 是否需要 TCP 三向握手?
如果你问的是一般意义上的问题,那么答案肯定是“是”,任何 HTTP 方法(如 POST)都需要 TCP 连接,而发起 TCP 连接的唯一方法是使用三向握手。
但是,如果您在特定情况下询问,也许如果您正在捕获自己的流量并且在向网站提交内容后没有看到 3 次握手,那么答案就不那么简单了。我们必须先讨论一些与 HTTP 相关的概念,然后才能正确地回答它……
在 HTTP1.0 的原始版本中,您从网页请求的每个对象都需要为每个对象形成一个新的 TCP 连接。以以下简单的网站为例,其中包含一些文本和两张图片:
<HTML>
<HEAD>
<TITLE>My Title</TITLE>
</HEAD>
<BODY>
Stack Exchange Rules!
<IMG SRC="a.gif">
<IMG SRC="b.gif">
</BODY>
</HTML>
在传统的 HTTP1.0 中,将此网站加载到您的浏览器需要三个 TCP 连接(每个连接都有自己的 3 次握手和 4 次关闭)。
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
注意上面有27个包,只下载三个:HTML页面本身(index.html),image a.gif,image b.gif。 (实际上会有超过 27 个数据包,但为了节省垂直空间,我只在 3 路握手和 4 路关闭中包含了 ACK,并在数据流中省略了 ACK)
为了提高 HTTP 的效率,引入了一个叫做“Connection Keepalive”的特性,它允许 HTTP 重新使用同一个 TCP 连接来请求多个对象。上述转让将减少为以下内容:
带有连接保持连接的 HTTP 1.1
--> SYN
SYN ACK <--
--> ACK
--> GET /index.html
<index.html> <--
--> GET /a.gif
<a.gif> <--
--> GET /b.gif
<b.gif> <--
--> FIN
ACK <--
FIN <--
--> ACK
请注意,只有一个 TCP 连接用于请求所有三个对象。这次只用了 13 个数据包,比之前的 27 个有了很大的改进。
我们必须讨论的对 HTTP 的最后一项改进是称为流水线的功能。此功能进一步提高了 HTTP 的效率,使客户端可以一次请求多个选项,而无需等待接收先前请求的对象。我来给你展示:
带流水线的 HTTP1.1
--> SYN
SYN ACK <--
--> ACK
--> GET /index.html
--> GET /a.gif
--> GET /b.gif
<index.html> <--
<a.gif> <--
<b.gif> <--
--> FIN
ACK <--
FIN <--
--> ACK
我们仍然只使用一个 TCP 连接,我们仍然只使用 9 个数据包。但是,在请求和接收每个对象之间,我们不必等待客户端和服务器之间的往返时间 (RTT)。如果你需要一个类比,想象你在一家餐馆,你需要盐、胡椒和番茄酱。一次向服务员/女服务员询问所有三样东西,还是一次问一个并等待他们回来再提出下一个请求,是否更有效?
(流水线与您的问题没有直接关系,但通常与 Keepalives 和其他 HTTP 效率功能一起描述,因此为了完整起见,我决定将其包含在此答案中)
现在我们终于可以回到你的问题了:
HTTP POST 是否需要 TCP 三向握手?
如果您打开与 Web 服务器的连接并使用 GET 方法下载网页,并且该 Web 服务器支持连接保持连接。对该 Web 服务器的后续请求(包括 POST 方法)可能会简单地重新使用已经存在的 TCP 连接。因此,该特定 POST 不需要新的 3 次握手,因为数据将在现有 TCP 连接中传输。
然而,连接 Keepalive 没有无限的持续时间。因此,如果下载完网页后,您等待一段时间后才发送 POST,则原始 TCP 连接可能已经关闭,在这种情况下,您的浏览器将不得不打开一个新的 TCP 连接来 POST 数据,这显然需要启动与 3 次握手。
由于许多浏览器和网络服务器使用不同的计时器来确定他们希望“连接保持活动”功能保持连接活动多长时间,因此我无法为您提供有关它们通常持续多长时间的可靠数字。
HTTP GET 和 HTTP POSTS 都使用 TCP。如果您问 POST 是否还需要 3 次 TCP 握手 (syn-synack-ack),它就像任何其他 TCP 连接一样。在任何应用程序协议(例如 HTTP)开始工作之前,都需要 TCP 握手。
仅供参考,您的三向握手不正确;它应该是“syn-synack-ack”
添加:
如果浏览器使用QUIC(Quick UDP Internet Connections,发音为 quick。由 Google 提出)HTTP 协议,则可以避免 3 路 TCP 握手。但 AFAIK 它在 Chrome 和 Google 中支持。
大多数软件更喜欢HTTP/2,它仍然是 TCP,但具有许多功能,它使用持久连接,然后为每个服务器服务器完成一次 3 次握手。
如果使用此协议,任何请求都可以避免 3 路 hanshake,包括 GET。
的确。但无论如何,仍然有一种方法可以提高效率——数据可以放入 SYN-SYNACK-ACK 数据包中,尽管在握手完成之前,数据无法使用。