TCP connection

基础概念:TCP连接与HTTP的关系

​TCP连接的作用​

  • 在客户端与服务器之间建立双向数据传输通道(类似"虚拟管道")。

  • HTTP请求和响应的数据包均需通过此通道传输。

​三次握手(Three-Way Handshake)​

  • TCP连接的建立需要客户端与服务器进行三次网络通信(SYN→SYN-ACK→ACK),会带来约1.5 RTT的延迟。

  • 频繁创建新连接会增加网络开销,影响性能。

HTTP各版本对TCP连接的优化演进

1. HTTP/1.0:短连接(Short-Lived Connections)

  • ​机制​

    • 每个HTTP请求需单独建立TCP连接,请求完成后立即关闭(Connection: close)。

    • 每个请求-响应周期都需要经历TCP三次握手和四次挥手。

  • ​缺点​

    • 高延迟:频繁连接的创建/销毁导致性能瓶颈(如加载网页需多次握手)。

    • 资源浪费:每次连接需占用服务器端口和内存。

2. HTTP/1.1:持久连接(Persistent Connections)

  • ​机制​

    • 默认启用长连接(Connection: keep-alive),单个TCP连接可复用多个HTTP请求。

    • 通过复用同一连接,后续请求无需重复三次握手。

    • 需显式关闭连接(如设置Connection: close或超时自动断开)。

  • ​优点​

    • 减少握手次数,降低延迟,提升页面加载速度。

    • 支持管道化(Pipelining,理论优化):允许连续发送多个请求(但响应需按序返回,易队头阻塞)。

3. HTTP/2:多路复用(Multiplexing)

  • ​机制​

    • 在单个TCP连接上实现多路并行传输(多个请求/响应可交错传输)。

    • 通过二进制分帧层(Binary Framing)将数据拆分为独立帧,实现并发传输。

  • ​优点​

    • 彻底解决HTTP/1.1的队头阻塞问题。

    • 更高的连接利用率,减少延迟(如页面资源可并行加载)。

技术演进的核心目标

  • 减少握手次数​​:通过复用TCP连接降低延迟(HTTP/1.1)。

  • ​提升传输效率​​:通过多路复用突破串行限制(HTTP/2)。

  • ​未来方向​​:HTTP/3基于QUIC协议(UDP),彻底规避TCP队头阻塞问题。

TCP 报文格式

源端口 (16位) 0-15
目的端口 (16位) 16-31
序列号 (32位) 32-63
确认号 (32位) 64-95
数据偏移 (4位)
保留 (6位) 96-105
控制标志 (6位)
URG ACK PSH RST SYN FIN
106-111
窗口大小 (16位) 112-127
校验和 (16位) 128-143
紧急指针 (16位) 144-159
选项 (长度可变) 160-191+
数据 (可变长度)

​源端口 & 目的端口​​(各16位)

标识发送方和接收方的应用程序端口。

​序列号 & 确认号​​(各32位)

序列号标记数据包顺序;确认号表示已接收的数据,用于可靠传输。

​数据偏移​​(4位)

指示TCP报头长度(以4字节为单位),确定数据起始位置。

​保留​​(6位)

未使用,通常置零。

​控制标志​​(6位)

  • ​URG​​:紧急数据有效

  • ​ACK​​:确认字段有效

  • ​PSH​​:接收方应立即推送数据至应用层

  • ​RST​​:强制断开连接

  • ​SYN​​:发起连接请求

  • ​FIN​​:终止连接

需要注意的是:不要将确认序号Ack与标志位中的ACK搞混了。确认方Ack=发起方Seq+1,两端配对。

​窗口大小​​(16位)

接收方可接收的数据量(流量控制)。

​校验和​​(16位)

验证报头和数据完整性。

​紧急指针​​(16位)

配合URG标志,指向紧急数据末尾位置。

​选项​​(可变长度)

扩展功能(如最大报文段MSS、窗口缩放因子)。

​数据​​(可变长度)

传输的应用层有效载荷。

三次握手

第一次握手 (SYN)
客户端 服务器
源端口: 12345
目的端口: 80
序列号: 1000
SYN=1
第二次握手 (SYN-ACK)
服务器 客户端
源端口: 80
目的端口: 12345
序列号: 5000
确认号: 1001
SYN=1, ACK=1
第三次握手 (ACK)
客户端 服务器
源端口: 12345
目的端口: 80
确认号: 5001
ACK=1

第一次握手

首先客户端向服务器端发送一段TCP报文

标记位为SYN,表示“请求建立新连接”; 序号为Seq=X(X一般为1); 随后客户端进入SYN-SENT阶段。

第二次握手

服务器端接收到来自客户端的TCP报文之后,结束LISTEN阶段。并返回一段TCP报文,其中:

标志位为SYN和ACK,表示“确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接”(即告诉客户端,服务器收到了你的数据); 序号为Seq=y; 确认号为Ack=x+1,表示收到客户端的序号Seq并将其值加1作为自己确认号Ack的值;随后服务器端进入SYN-RCVD阶段。

第三次握手

客户端接收到来自服务器端的确认收到数据的TCP报文之后,明确了从客户端到服务器的数据传输是正常的,结束SYN-SENT阶段。并返回最后一段TCP报文。其中:

标志位为ACK,表示“确认收到服务器端同意连接的信号”(即告诉服务器,我知道你收到我发的数据了);序号为Seq=x+1,表示收到服务器端的确认号Ack,并将其值作为自己的序号值; 确认号为Ack=y+1,表示收到服务器端序号Seq,并将其值加1作为自己的确认号Ack的值; 随后客户端进入ESTABLISHED阶段。

四次挥手

四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。 发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

第一次挥手 (FIN-ACK)
客户端 服务器
源端口: 12345
目的端口: 80
序列号: 5001
确认号: 8001
FIN=1, ACK=1
第二次挥手 (ACK)
服务器 客户端
源端口: 80
目的端口: 12345
确认号: 5002
ACK=1
第三次挥手 (FIN-ACK)
服务器 客户端
源端口: 80
目的端口: 12345
序列号: 8001
确认号: 5002
FIN=1, ACK=1
第四次挥手 (ACK)
客户端 服务器
源端口: 12345
目的端口: 80
确认号: 8002
ACK=1

总结

TCP三次握手目的

是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误

TCP四次挥手目的

因为tcp是全双工模式,接收到FIN时意味将没有数据再发来,但是还是可以继续发送数据