TCP协议的三次握手与四次挥手
TCP报文的格式
先明确一个问题:每一次client与server交换的东西叫 —— 报文段
TCP是面向连接的,安全可靠的协议,三次握手正是为了保证能够建立一个安全可靠的连接
何为安全,如何保证安全?
- 双方都已经就绪
- 已经做好后续数据交换的准备(协商得知对方的序列号)
三次握手的全过程(客户端企图建立连接)
-
1.客户端向服务端发起建立连接的请求
在这个建立连接的请求中,标志位至1(SYN=1),随机生成一个初始的32位序列号seq=x(initial sequence number)
-
2.服务端如果同意与客户端建立连接,那么需要回复一个确认帧,其中标志位至1(SYN=1),ACK位至1(ACK=1),随机生成一个序列号seq=y,确认序号ack=x+1 [有了ACK=1 和 ack=x+1,客户端就知道了服务端同意与自己建立联系]
Question:为什么2次握手🤝不行?
到目前为止,客户端client已经知道了自己既能给server发消息也能接受server的消息,但是server只晓得client发给自己的信息可以收到,但是自己发给client的消息client能不能接受的到这个不知道,所以2次握手不够(这一条也就是很多面经里写到的“同步序列号问题”,即client与server就server的初始序列号问题无法达成一致,这样后面很有可能会导致错误的连接)
Question:4次握手🤝呢?
3次握手就已经能将client与server序列号同步问题解决,多加一次只会浪费资源降低效率
- 3.客户端返回消息确认帧,其中ACK标志位至1(ACK=1),消息确认序号ack=y+1
至此,client和server都知道了彼此之间能给对方发消息也能收到对方的消息
seq起到的一个很重要的作用:
若client的initial sequence number = 1000,那么,它之后发送的报文seq number都是1001、1002、1003...,若突然出现了一个seq number = 900,表明该报文不合法(校验合法的作用)
像3次握手这种机制叫做“双工通信”
四次挥手的全过程(客户端试图断开连接)
因为是client发起的断开,所以在此时client是一定做好断开准备的
1.客户端发送,FIN位至1(FIN=1),随机生成一个初始序列号seq=x
2.服务端发送ACK=1,ack=x+1,seq=u(这一次的意义好比:服务端向客户端说:“好的,收到你请求断开的请求,我目前并未准备好,待我准备好时再通知你!”)
Question:为什么挥手👋一定要4次?
这里server不一定能够做好断开准备
3.服务端继续发送FIN=1,ACK=1,seq=v(“我准备好了,分手吧!”),ack=x+1
4.客户端发送ACK=1,ack=v+1,seq=x+1
Tip:你是否对SYN、FIN、ACK...弄不清楚,什么时候该位为1,何时该位为0?
1)SYN表示建立连接;
2)FIN表示关闭连接;
3)ACK表示响应;
附上两张官方讲解图: