TCP详解

TCP详解
X![]() |
---|
![]() |
TCP报文 |
TCP三次握手流程
步骤 | 方向 | 数据包内容 | 作用 |
---|---|---|---|
第一次握手(SYN) | 客户端 → 服务器 | SYN=1, seq=x(客户端随机生成初始序列号x | 客户端请求建立连接,并发送自己的初始序列号。 序号字段seq被设置了一个初始值x作为TCP客户进程所选择的初始序号。 |
第二次握手(SYN+ACK) | 服务器 → 客户端 | SYN=1, ACK=1, seq=y, ack=x+1(服务器随机生成初始序列号y,确认客户端的x) | 服务器确认客户端的连接请求,并发送自己的初始序列号及对客户端的确认号。 序号字段seq被设置了一个初始值y,作为TCP服务器进程所选择的初始序号。确认号字段ack的值被设置成了x+1,这是对TCP客户进程所选择的初始序号seq的确认。 |
第三次握手(ACK) | 客户端 → 服务器 | ACK=1, seq=x+1, ack=y+1(客户端确认服务器的y) | 客户端确认服务器的连接请求,连接正式建立。 序号字段seq 被设置为x+1,这是因为TCP客户进程发送的第一个TCP报文段的序号为x,并且不携带数据,因此第二个报文段的序号为x +1。确认号字段ack被设置为y + 1,这是对TCP服务器进程所选择的初始序号的确认。 |
若TCP仅采用二次握手,错误响应会引发哪些核心问题?
核心问题1:半连接资源泄漏问题
三次握手的主要目的是确认自己和对方的发送和接收都是正常的,从而保证了双方能够进行可靠通信。若采用两次握手,当第二次握手后就建立连接的话,此时客户端知道服务器能够正常接收到自己发送的数据,而服务器并不知道客户端是否能够收到自己发送的数据。
我们知道网络往往是非理想状态的(存在丢包和延迟),当客户端发起创建连接的请求时,如果服务器直接创建了这个连接并返回包含 SYN、ACK 和 Seq 等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直接收不到返回的数据包。由于客户端可能设置了一个超时时间,一段时间后就关闭了连接建立的请求,再重新发起新的请求,而服务器端是不知道的,如果没有第三次握手告诉服务器客户端能否收到服务器传输的数据的话,服务器端的端口就会一直开着,等到客户端因超时重新发出请求时,服务器就会重新开启一个端口连接。长此以往, 这样的端口越来越多,就会造成服务器开销的浪费。
核心问题2:陈旧重复SYN导致连接混乱
网络延迟引发的旧SYN到达: 客户端发送SYN(初始序列号seq=x)后,因网络拥塞或主机崩溃,该SYN未被服务器接收。客户端重启后重新发送SYN(seq=y,y≠x)。此时,旧的SYN(seq=x)可能因网络延迟到达服务器。
二次握手下的混乱: 若采用二次握手,服务器收到旧SYN后会立即分配资源并回复SYN+ACK(ack=x+1)。客户端收到后,发现期望的确认号应为y+1而非x+1,但因二次握手无第三次确认步骤,客户端无法通知服务器该SYN已过期。服务器可能因此建立错误连接,导致后续数据传输失败。
三次握手序列号校验机制: 客户端在第三次握手时发送ACK(ack=y+1),明确告知服务器其期望的初始序列号。若服务器收到ack=x+1(对应旧SYN),将识别为无效连接请求,避免建立错误连接。