相关名词
ACK:代表此次报文是确认报文。
SYN:代表此报文是建立连接报文。
ack:代表需要下次接受的报文序号。
seq:代表此次报文序号。
MSL:指的是Maximum Segment Lifetime:一段TCP报文在传输过程中的最大生命周期。
三次握手
- 开始时客户端发送创建连接报文。 SYN代表请求建立连接。 seq代表此次报文序号为x。并且进入SYN-SENT(连接发送)状态。
- 服务器监听到请求连接报文后,进入SYN-RCVD(连接收到)状态,并发送SYN请求建立连接,并且ACK =1 代表确认建立连接。seq序号为y。ack代表需要客户端下次报文序号为x+1.
- 客户端收到服务器发送的确认连接报文后,进入ESTABLISHED(连接建立)状态,并发送一个确认收到了服务器发来的确认建立连接报文的报文。ACK=1代表确认连接。seq为x+1,ack需要服务器端下次报文序号为y+1.
- 服务器接收到客户端发来的确认确认连接报文后,进入ESTABLISHED(连接建立)状态。
为什么是三次握手不是二次或者四次?
如果是两次握手,服务器端确认报文丢失了,客户端不知道是自己第一次发送请求建立报文服务器未收到还是如何,只能重新发送建立连接报文,会引起资源浪费。或者是客户端发送两次连接报文,第一次网络延迟未到达,客户端发送第二次连接报文,此次连接服务器响应并建立连接,此时第一次创建连接报文到达服务器,服务器又为该客户端建立连接,如果是三次握手则不会又这种资源浪费出现。
三次握手已经确认了客户端和服务器端的接受和发送能力都完好,即便是四次五次握手都不能百分百的确认连接建立的成功性,所以采取三次握手是最合适的。
四次挥手
- 客户端主动关闭连接,发起FIN报文,seq序号为u,并且状态改变为FIN-WAIT-1(关闭连接等待1).
- 服务器接收到客户端的关闭连接后,会立即发送一个报文段ACK表示接受到关闭连接报文,seq序号为v,下次接受序号为u+1,并通知应用进程连接关闭,状态进入CLOSE—WAIT(关闭等待),因为关闭连接是客户端发送的所以有可能服务器端还有数据报文未发送完成正在处理。
- 服务器处理完数据后发起FIN,ACK报文表示确认关闭连接,序号为w,不是v+1的原因是这两段报文中间会发送其他数据报文,确认接受报文序号为u+1.状态进入LAST-ACK(最后确认阶段)。
- 客户端接受到第一次确认报文后,改变状态为FIN-WAIT-2(关闭连接等待2),等待服务器的确认结束连接报文,接收到第二次结束连接报文后状态改变为TIME-WAIT(超时等待状态),防止服务器的数据报文到达后无法接受和自己发送的确认结束报文(ACK确认,序号为u+1,确认接受序号为w+1)服务器未收到。
- 服务器接受到确认报文后进入CLOSE(关闭状态)。
- 客户端等待2MSL后也进入CLOSE(关闭状态),如果在1MSL内接收到了服务器再次发来的FIN确认报文说明之前发送的ACK确认结束连接报文服务器未收到,所以重发。如果等待了2MSL未接收到服务器的其他报文则进入CLOSE状态。
为什么是三次握手而挥手是四次?
因为关闭连接是客户端提出的,此时服务器端有可能有数据报文未发送完成,但是需要立即答复客户端的结束连接报文,所以将握手种的第二次SYN和ACK报文分成两次发送,一次为确认接受到了结束连接报文(ACK报文),一次为真的结束连接了(FIN报文)。
建立连接和结束连接顺序?
需要注意的是建立连接时是客户端先进入连接建立阶段(ESTABLISHED),结束时是服务器先进入关闭状态(CLOSED)。
参考博客:https://blog.csdn.net/qzcsu/article/details/72861891?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
笔者理解有限,如果有错误的地方还望指正共同学习。