三次握手
- 第一次:客户端发送SYN标识位,seq序列号到服务器端,客户端状态:
SYN_SEND
- 第二次:服务器端发送SYN标识位,ACK标识位,ack确认号,seq序列号, 服务器端状态:
SYN_RCVD
- Ack=J+1(J为第一次seq的值)
- 客户端发送ACK标识位,ack确认号,客户端状态:
ESTABLISHED
- Ack=K+1(K为第二次seq的值)
- 服务器端收到ACK,进入
ESTABLISHED
,不算握手Ack=Seq+1
字段认识
- seq: 序号(解决网络包乱序)
- ack:确认号(解决网络包丢失)
- 标识位6个
- ACK:确认号(Acknowledgement)
- SYN:请求同步(Synchronization)
- URG:紧急指针
- PUSH:接收方应尽快将这个报文交给应用层
- RST:重置连接
- FIN:释放一个连接
1表示开启,0表示关闭
使用wireshark来分析三次握手的过程
第一次握手分析
- 619: 50595 -> 3000
- [SYN]
- Seq = 0
- MSS=1460,表示最大报文长度
第二次握手分析
- 620: 3000 -> 50595
- [SYN, ACK]
- Seq=0
- Ack=1
第三次握手分析
- 621: 50595 -> 3000
- [ACK]
- Seq=1
- Ack=1
为什么握手是三次?
因为要保持连接和可靠性约束,TCP
协议要保证每一条发出的数据必须给出ACK
(也就是响应)。
- 第一次:客户端发送
SYN
表示请求建立连接(服务端知道了客户端有发送能力) - 第二次:服务器端发送
SYN
ACK
之后,表示服务器端已经准备好了(客户端知道服务端具有接收发送能力) - 第三次:服务器端此时还不知道客户端是否也准备好,所以需要第三次握手
四次挥手
断开连接时要发送四次数据,故称四次挥手
- 第一次挥手:挥手前服务器与客户端都处于ESTABLISHED状态。客户端发送一个FIN报文,用来关闭客户端到服务器的数据传输,此时客户端处于FIN_WAIT_1状态
- 第二次挥手:当服务端收到FIN之后,会发送ACK报文,并且把客户端的序列号值加1作为ACK报文的序列号值,表明已经收到客户端的报文了,此时服务端处于CLOSE_WAIT状态。
- 第三次挥手:如果服务端同意关闭连接,则会向客户端发送一个FIN报文,并且指定一个序列号,此时服务端处于LAST_ACK状态
- 第四次挥手:当客户端收到ACK之后,处于FIN_WAIT_2状态。待收到FIN报文时发送一个ACK报文作为应对,并且把服务端的序列号值+1作为自己ACK报文的序列号值,此时客户端处于TIME_WAIT状态。等待一段时间后会进入CLOSED状态,当服务端收到ACK报文之后,也会变为CLOSED状态,此时连接正式关闭
为什么挥手需要四次
- 当服务端收到客户端FIN报文后,发送的ACK报文只是用来应答的,并不表示服务端也希望立即关闭连接
- 当只有服务端把所有的报文都发送完了,才会发送FIN报文,告诉客户端可以断开连接了,因此在断开连接时需要四次挥手