Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TCP #83

Open
lovelmh13 opened this issue Jun 21, 2021 · 0 comments
Open

TCP #83

lovelmh13 opened this issue Jun 21, 2021 · 0 comments

Comments

@lovelmh13
Copy link
Owner

lovelmh13 commented Jun 21, 2021

TCP 的三次握手和四次挥手

是什么

三次握手是 TCP 的链接阶段,四次挥手是 TCP 的断开阶段。

TCP 一共有三个阶段:链接 - 传输 - 断开

为什么

为什么是三次挥手

肯定不能只有一次。既然是双方,那么肯定至少需要互相说句话,至少两次。

那么两次呢?两次也不行,因为第一次客户端要发送标志给服务端,第二次服务端做出应答,如果没有第三次,服务端就要干等了。

所以第三次客户端还要对服务端的回应进行回应。三次,刚刚好。

为什么是四次挥手

TCP 是全双工的,双方可以互相通信。单方发消息的时候,另一方可能也在发消息。所以断开的时候,需要双方都知道要断开。

断开的时候也是

  1. 客户端发消息说想要断开,
  2. 然后服务端收到以后要发送回复消息
  3. 但是可能要发的数据还没有发完,所以还要单独再发送最后的数据,这就多占用了一次挥手
  4. 收到服务端最后的确认以后,客户端对服务端做出回应,等待 2MSL 时间服务端没有再回应,就可以关闭了。这个 2MSL 的时间,就是 time_wait

为什么没有第五次服务端确认客户端的消息了呢?因为不需要了呀,服务端都已经发送完了要发的数据了,只要接收到客户端收到消息的回复就可以了。

怎么做

三次挥手

为了确保TCP协议的准确性,有了三次握手策略。

如果握手时在某个阶段中断,TCP协议会再次以相同的顺序发送相同的数据包

为了保证准确性,握手的时候使用了TCP的标志, 同步(SYN 即 synchronize)和 确认(ACK 即 acknowledgement)

三次握手即:

  • 客户端 发送同步标志(SYN)给 服务端 (此时客户端是syn_sent状态,服务端是syn_rcvd状态,都称为半打开状态)
  • 服务端 接收到了 SYN,然后又发送同步和确认标志(SYN/ACK)给 客户端(此时客户端进入established状态)
  • 客户端 接到了接收端的 SYN/ACK ,再次发送ACK给 服务端 ,确定链接(此时服务端也进入established状态)
    借用一张老錢的图:

sp20200131_144017_503

通俗点儿讲:

  • 客户端:我是A
  • 接收端:收到,我是B
  • 客户端:明白

四次挥手

  • 客户端 发送 FIN 标志给 服务端
  • 服务端 发送ACK 标志给 客户端
  • 还是 服务端 发送 FIN 标志给 客户端
  • 客户端 发送 ACK 标志给 服务端
  • 客户端 等待2MSL没有等到回复,就关闭

每个MSL是2分钟,由RFC协议规定的。只于为什么是2MSL,这个不清楚

借用一张老錢的图:

sp20200131_142031_782

上面有一个非常特殊的状态time_wait,它是主动关闭的一方在回复完对方的挥手后进入的一个长期状态,这个状态标准的持续时间是4分钟,4分钟后才会进入到closed状态,释放套接字资源。不过在具体实现上这个时间是可以调整的。

有什么缺陷

可以看这个:#69

主要就是 「队头堵塞」「因为握手启动慢」的问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant