一、简述
1. 三次握手
C: syn
S: syn+ack
C: ack
2. 四次挥手
C: fin
S: ack
S: fin
C: ack
3. 为什么挥手时,S的ack和fin不一起发?
(1) 当S收到C的FIN报文时,仅仅表示C不再发送数据,但C还能接收数据。
(2) S是否现在关闭发送数据通道,需要上层应用来决定,不能自己决定。
二、为什么要三次握手四次挥手
1. 客户端和服务端都要确认 自己和对方 的 接收能力 和 发送能力。
(1) S收到C的syn包,可以确认S的接收能力OK,C的发送能力OK。
(2) C收到S的ack包,可以确认S的接收和发送能力OK,C的发送和接收能力都OK。
(3) S收到C的ack包,可以确认S的接收和发送能力OK,C的发送和接收能力都OK。
2. 另一个重要功能是交换序列号,以便让对方知道接下来接收数据的时候,如何按序列号组装数据。
三、连接队列
1. 三次握手过程中,C会分别处于SYN_SEND和ESTABLISHED状态, S会分别处于SYN_RCVD和ESTABLISHED状态。
ESTABLISHED状态时是还未被应用程序接受的。
2. 相应地,S 会维护两个队列,分别是处于SYN_RCVD的半连接队列,和处于ESTABLISHED的全连接队列。
如果这两个队列满了之后,就会出现各种丢包的情形。
四、客户端断开了连接,服务端能不能立刻感知?
服务端能否"立即"收到通知,存在以下几种情况:
1. 客户端正常关闭:通过FIN/ACK机制可即时感知
2. 客户端异常断开:依赖超时重传或Keep-Alive机制,存在分钟级延迟。(默认每2小时发送探测包,检测到3次失败后感知连接异常,并断开连接)
3. 两段完全无数据交互:若无Keep-Alive且长期无数据传输,服务端可能永远无法感知连接已断
五、其他介绍
1. TCP头部介绍
2. syn flood攻击 (DDos攻击)
3. 查看队列情况,调整连接队列参数
4. 抓包实例
原文地址 “三次握手,四次挥手”你真的懂吗?,包含: