TCP 的三次握手/四次挥手的过程

在这里插入图片描述

  • TCP 是一种面向连接的、可靠的字节流服务
  • TCP 连接中仅有两方可以彼此通信,广播和多播不用于 TCP
  • 使用校验和、确认、重传机制来实现可靠传输
  • 给数据分组进行排序,使用累积确认来保证数据的顺序不变和非重复
  • 用滑动窗口来实现流量控制,通过动态改变窗口的大小来进行拥塞控制

三次握手

  1. 客户端的 TCP 首先向服务器端的 TCP 发送一个特殊的 TCP 报文,报文的首部不包含应用层数据,其首部 SYN 标志位置 1。称该报文段为 SYN 报文段。并且还会随机选择一个初始序号(client_isn,isn 为 initial sequence number) 放在序号字段。该报文段会放到一个 IP 数据报中,发送给服务器。

  2. 包含 TCP SYN 报文段的 IP 数据报到达服务器主机,服务器从中抽取 TCP SYN 报文段,为该 TCP 连接分配 TCP 缓存和变量,并向该客户 TCP 发送允许连接的报文段,该报文段也不包含应用层数据。但是其首部包含了三个重要的信息:

    1. SYN 置 1
    2. 首部的确认号字段被置为 client_isn + 1
    3. 服务器选择自己的初始序号(server_isn),将其放入序号字段

    该报文段意义为:我已经收到了你发的 SYN,该分组序号为 client_isn,我同意建立连接,我自己的初始序号为 server_isn。该允许连接的报文段有时称为 SYNACK 报文段(SYNACK segment)

  3. 客户端收到 SYNACK 后,为该连接分配缓存和变量,客户端向服务器发送另外一个报文段,该报文段对服务器的允许连接的报文段进行了确认(确认字段放 server_isn + 1),由于连接已建立,因此 SYN 被置 0。并且这一阶段可以在报文段负载中携带需要发送的数据。(注意:前两步中 SYN 会消耗一个序列号,第三步里单纯的 ACK 不消耗序列号)

在这里插入图片描述
通过这三步之后,客户端与服务器端就可以互相发送数据的报文段了,此后的每一个报文段,SYN 都会置为 0。该建立连接的过程称为三次握手(three-way handshake)

  • 为什么需要初始序号?

TCP 是双向的可靠连接,为了建立双向的可靠连接,TCP 通信的双方通过分别维护一个序列号来保证通信的可靠性。

  • 为什么需要三次握手,而不是两次?

根本原因仍然是为了保证通信的双方都能够得到对方的序列号(sequence number)

假如只有两次握手,那么只有 server 端知道了 client 的初始序列号,而 client 端不知道 server 端的初始序列号。

见知乎

四次挥手

  1. 客户端向服务器发送一个 TCP 报文,报文中 FIN 置 1,seq = x,表示客户端已经不再发送数据,但是仍然可以接收数据。发送完毕后,客户端进入 FIN_WAIT_1 状态 (此处选择的是客户端决定关闭连接,注意:服务器也可以选择关闭连接)
  2. 服务器收到客户端的 FIN,向客户端发送 ACK 表示确认收到,此时服务器只是回应消息,并没有准备好关闭连接,发送完毕后,服务器进入 CLOSE_WAIT 状态。客户端收到这个确认包之后进入 FIN_WAIT_2 状态,等待服务器关闭连接
  3. 服务器准备好关闭连接,向客户端发送结束连接请求,FIN 置 1。发送完毕后服务器进入 LAST_ACK 状态,等待来自客户端的最后一个 ACK
  4. 客户端收到服务器的关闭请求,发送一个 ACK 确认包,进入 TIME_WAIT 状态,等待可能出现的要求重传的 ACK 包。服务端收到这个确认包之后,关闭连接,进入 CLOSED 状态。在客户端等待了某个固定的时间(两个最大段生命周期 2MSL(Maximum Segment Lifetime))后,没有收到服务端的 ACK,认为服务器已经正常关闭连接,此时自己也关闭连接,进入 CLOSED 状态。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考资料

《计算机网络:自顶向下》

https://hit-alibaba.github.io/interview/basic/network/TCP.html

posted @ 2020-08-04 11:57  winechord  阅读(71)  评论(0编辑  收藏  举报