说说的想法
我也是参考文献的,只是参考好几篇文章才弄懂,我只是做个笔记记录一下三次握手和四次挥手的内容,以及添加自己的了解,后面方便自己忘记了再回顾。链接的这篇文章介绍的比较详细,面试中的问题也都涉及到了,如果主要想深入了解的话看这篇大佬的文章吧!TCP 三次握手与四次挥手面试题
TCP头部格式
在我刚开始想要了解TCp三次握手与四次挥手的时候,直接去的时候不明白中间ACK等的含义,所以了解握手与挥手之前,需要提前先了解TCP头部格式,明白内部结构以及作用,才能更好地去了解怎么握手与挥手的。
序列号(Sequence number):
在建立连接时,由计算机生成的随机数作为初始值,通过SYN包传给接收方主机,每发送一次数据,就会累加一次这个数据字节数的大小,用来解决网络包乱序问题。
我理解的是:假设就是自己生成初始序列号为100,发送过去之后自己+1变成101,对方收到之后会发过来100+1,自己收到之后核对一下,哎,和我的一样的都是101,说明对方收到了。
确认应答号(Acknowledge number):
用来表示期盼下一次收到的数据的序列号,发送端收到这个确认应答后,可以认为这个序号以前的数据都被正常接收。用来解决丢包问题。
我的理解:这个的话就是自己发过去的100,对方收到之后变成100+1,就是上述说的对方发过来的100+1,然后放在【确认应答号】,再发回来
控制位:
- SYN(synchronous):
-【建立连接】该位为1时,表示希望建立连接,并且设置好序列号的初始值。 - ACK(acknowledgement):
-【确认连接】该位为1时,确认应答序号有效,TCP规定除了最初建立连接时的SYN包之外,该位必须设置位1 。 - RST(reset):
-【重置】该位为1时,表示TCP连接中出现异常必须强制断开连接。 - FIN(finish):
-【断开连接】该位为1时,表示今后不会有数据发送,希望断开连接,当通信结束希望断开连接时,通信双方的主机之间就可以相互交换FIN为1的TCP字段。
TCP三次握手
刚开始的时候,客户端和服务端都处于 CLOSED 状态,首先,服务端主动监听某个端口,处于 LISTEN 状态,然后客户端进行连接
(1)SYN / Seq Num = client_isn:
- 客户端会随机初始化序号(client_isn),将此序号置于 TCP 首部的「序列号」字段中,同时把 SYN 标志位置为 1 ,表示 SYN 报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于 SYN-SENT 状态。
- 客户端发送一个TCP的SYN标志位置1的包指明客户打算连接的服务器的端口,以及初始序号(client_isn),保存在包头的序列号(Sequence Number)字段里。
- 我的理解很简单的,就是客户端发过去:(SYN)我想连接你,可以吗?
(2)SYN+ACK / Ack Num = client_isn+1 / Seq Num = server_isn:
- 服务端收到客户端的 SYN 报文后,首先服务端也随机初始化自己的序号(server_isn),将此序号填入 TCP 首部的「序列号」字段中,其次把 client_isn + 1放在TCP 首部的「确认应答号Acknowledge number」字段中 , 接着把 SYN 和 ACK 标志位置为 1。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN-RCVD 状态。
- 服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号(Acknowledgement Number)设置为客户的client_isn加1以.即client_isn+1。
- 我的理解就是服务器发过去:(ACK)我同意连接你,(SYN)我也想连接你可以吗?
(3)ACK / Ack_Num = server_isn:
- 客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部 ACK 标志位置为 1 ,其次「确认应答号」字段填入 server_isn + 1 ,最后把报文发送给服务端,这次报文可以携带客户到服务器的数据,之后客户端处于 ESTABLISHED 状态。
- 服务器收到客户端的应答报文后,也进入 ESTABLISHED 状态。
- 我的理解就是客户端发过去:我也同意连接你。
TCP四次挥手
- 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN(断开连接)标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
- 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSED_WAIT 状态。
- 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
- 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
- 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
- 服务器收到了 ACK 应答报文后,就进入了 CLOSED 状态,至此服务端已经完成连接的关闭。
- 客户端在经过 2MSL 一段时间后,自动进入 CLOSED 状态,至此客户端也完成连接的关闭。
- 我的理解就是:
客户端:(FIN)我想断开连接啦可以吗?
服务器:(ACK)我收到啦!等等我吧剩下的任务做完哈!
服务器:(FIN)好的我可以断开啦!
客户端:(ACK)收到呢,再见!
大体就是这样吧,如果有理解错误的地方还请大家提出来。感谢!