图解TCP三次握手与四次挥手(附状态变迁与实战抓包)

发布时间:2026/7/15 16:48:14
图解TCP三次握手与四次挥手(附状态变迁与实战抓包)
1. TCP三次握手从零开始建立可靠连接想象你要给朋友打电话TCP三次握手就像打电话前的确认过程。第一次握手相当于你拨号第二次是朋友接起电话说喂第三次是你回应喂是我。只有完成这三步你们才能开始正常通话。具体过程拆解第一次握手客户端发送SYN1的报文同步序列编号随机生成初始序列号seqx。这就像你举起手说我要发言此时客户端进入SYN_SENT状态。第二次握手服务端回复SYN1, ACK1的报文确认号ackx1同时发送自己的初始序列号seqy。相当于朋友不仅回应你还说了句我听到你了。服务端进入SYN_RCVD状态。第三次握手客户端发送ACK1确认号acky1。就像你最后确认好的我们开始吧。双方进入ESTABLISHED状态。为什么不是两次假设网络延迟导致旧的SYN包突然到达服务端如果是两次握手服务端会直接建立连接等待数据而客户端根本不知情。三次握手确保了双方都能确认对方的收发能力。实战抓包示例Wireshark截图描述No. 时间 源IP 目标IP 协议 长度 信息 1 0.000000 192.168.1.2 → 10.0.0.3 TCP 74 [SYN] Seq0 Win64240 2 0.023451 10.0.0.3 → 192.168.1.2 TCP 74 [SYN,ACK] Seq0 Ack1 Win65535 3 0.046892 192.168.1.2 → 10.0.0.3 TCP 66 [ACK] Seq1 Ack1 Win64240可以看到序列号从0开始每次ACK都会对收到的序列号1确认。2. TCP状态机连接建立中的状态变迁TCP连接过程中客户端和服务端会经历多个状态变化。就像电梯运行要经过开门-进人-关门-上升等状态TCP也有自己的状态流程图。关键状态解析LISTEN服务端像待机的电话等待任何来电SYN_SENT客户端已拨号等待对方接听SYN_RCVD服务端已接听并回应等待最终确认ESTABLISHED通话通道建立成功状态转换图示例客户端: CLOSED → SYN_SENT → ESTABLISHED 服务端: CLOSED → LISTEN → SYN_RCVD → ESTABLISHED常见问题场景如果第二次握手丢失客户端会超时重传SYN默认等待约3秒服务端长时间收不到第三次握手会重传SYNACK通常重试5次3. 四次挥手优雅地断开连接断开连接比建立更复杂就像挂电话前要说我说完了-好的-那我挂了-再见。TCP是全双工的必须分别关闭两个方向的数据流。详细过程第一次挥手主动方发送FIN1sequ进入FIN_WAIT_1第二次挥手被动方回复ACK1acku1进入CLOSE_WAIT第三次挥手被动方发送FIN1seqv进入LAST_ACK第四次挥手主动方回复ACK1ackv1进入TIME_WAIT为什么需要TIME_WAIT确保最后一个ACK能到达等待2MSL通常1-4分钟让网络中残留的旧报文完全消失避免影响新连接抓包实例分析No. 时间 源IP 目标IP 协议 长度 信息 1 15.231000 192.168.1.2 → 10.0.0.3 TCP 66 [FIN,ACK] Seq101 Ack201 2 15.254321 10.0.0.3 → 192.168.1.2 TCP 66 [ACK] Seq201 Ack102 3 16.123456 10.0.0.3 → 192.168.1.2 TCP 66 [FIN,ACK] Seq201 Ack102 4 16.145678 192.168.1.2 → 10.0.0.3 TCP 66 [ACK] Seq102 Ack2024. 实战抓包分析Wireshark解密TCP对话Wireshark就像网络世界的显微镜让我们能看到TCP报文最真实的模样。以下是关键分析要点标志位识别技巧SYN包Flags字段显示0x002 (SYN)ACK包Flags字段显示0x010 (ACK)FIN包Flags字段显示0x001 (FIN)序列号跟踪方法找到三次握手的第一个SYN包记录初始序列号后续每个包的Ack号都应对应上一个包的Seq数据长度传输文件时可以看到Seq号随数据长度递增典型异常情况重传包相同Seq号重复出现乱序包后发的包Seq号反而更小丢包Ack号长时间不更新过滤表达式推荐tcp.stream eq 0分析单个TCP流tcp.flags.syn1 and tcp.flags.ack0找初始SYNtcp.analysis.retransmission查找重传包