TCP三次握手
Wireshark配置
为了分析TCP三次握手过程,首先通过浏览器访问一个网页。
通过F12获取该网页的IP地址,以IP地址104.16.7.49为例。
我们可以通过设置Wireshark的过滤条件快速找到目标IP地址的数据。
过滤语句为 ip.src == 104.16.7.49 or ip.dst == 104.16.7.49
含义为源IP地址为104.16.7.49或者目标IP地址为104.16.7.49,
因为在TCP三次握手的过程中存在 源地址(浏览器/客户端) → 目标地址(网页/服务器) 以及目标地址 → 源地址 的数据交换
另外可以在过滤IP地址后再加上对协议类型的过滤,如ip.src == 104.16.7.49 or ip.dst == 104.16.7.49 and tcp
第一次握手 客户端发送SYN信号
该条数据中可见,源IP地址为192.168.50.176(本地IP地址),目标IP地址为104.16.7.49,
第二次握手 服务器收到SYN,发送SYN + ACK
数据中的Sequence Number: 0 (relative sequence number)为对应的数据号,原始seq = 875405482,
同理原始ack = 4251030294,为第一次握手中的原始seq(4251030293) + 1
第三次握手 客户端收到SYN + ACK,发送ACK
第三次握手中的seq == 第二次握手中的ack,
第三次握手中的ack == 第三次握手中的seq + 1
TCP常见问题
1. 三次握手
1.1 为什么要三次握手,两次不行吗
第一次握手:客户端向服务端发出SYN数据包;确认了客户端的发送能力。
第二次握手:服务端收到客户端SYN数据包,向客户端发送SYN + ACK数据包;服务端确认了自己的接收能力和发送能力,以及客户端的发送能力。
如果仅有这两次握手,服务端无法确认客户端的接收能力。
第三次握手:客户端收到服务端的SYN + ACK数据包,发送ACK数据包;服务器收到客户端的ACK数据包后,可确认客户端的接收能力。
三次握手主要为了防止客户端已失效的请求数据包又发送到了服务端而产生连接的误判。
假设客户端发送了一个数据包A,但因各种原因导致了滞后,便超时重发了数据包B。数据包B正常建立了连接,传输完成后释放了连接。
若此时数据包A到达了服务端,服务端误判为客户端发送了一次新的请求。如果没有三次握手,服务端此时发送了确认的数据包之后,就建立了连接,并等待客户端发送数据。
但客户端并没有在此时发出建立连接的请求,不会因为服务端的确认而发送数据。导致服务端持续等待直至超出等待时间上限,浪费了服务器的资源。
如果采用三次握手,客户端收到服务端的确认数据包后便不会向服务器发送确认,服务器因没有收到确认,便知道客户端没有请求建立连接,不会继续等待。
1.2 如果采用四次握手
造成资源的浪费,三次握手结束之后就已可以确认服务端、客户端双方的发送和接收能力。
2. 四次挥手
2.1 四次挥手的原因
TCP的半关连接是指:TCP连接只有一方发送了FIN,另一方没有发出FIN包,仍然可以在一个方向上正常发送数据。
在第一次挥手之后,服务端收到客户端的FIN数据包,仅表示客户端停止发送,但因为TCP的半关闭,客户端仍可接收数据。
服务端发送ACK数据包表示已接收客户端的FIN数据包,若服务端此时还有数据未发送完成,继续发送数据,发送完成后发送FIN + ACK数据包给客户端表示表示同意关闭连接。
2.2 释放连接时等待2MSL的意义
为了确保第四次挥手时客户端发送的ACK数据包能够到达服务器。如果该ACK数据包丢失,服务器便无法确认自己发送的FIN + ACK报文被接收。
若不等待2MSL(maximum segment lifetime,最长报文寿命),客户端发送ACK后直接关闭,如果ACK数据包丢失,服务器无法正常进入CLOSED状态。
若等待2MSL,服务器没有收到ACK数据包后一段时间后会超时重传FIN + ACK,客户端收到之后也会重传ACK数据包并重置2MSL等待时间,直到客户端和服务器双方都正常进入CLOSED状态。