简谈 TCP 协议的三次握手和四次挥手

Author Avatar
WincerChan 6月 23, 2017
  • 在其它设备中阅读本文章

最近计算机网络考试,无奈本学期没听多少,对三次握手和四次挥手的概念是模模糊糊,在看了哈工的网课后,了解了一些,就写篇博客记录和分享一下。

TCP 定义

传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的 RFC 793 定义。

TCP 建立链接

TCP 用三次握手过程来创建一个连接。

图片来自网络

但是为什么是三次握手来保证一个稳定的连接呢,两次行不行?四次不行吗?

引用网上一个通俗的例子来让我们快速了解一下,当然这个例子并不严谨,但对我们的理解是有帮助的。

三次握手:

A:“喂,你听得到我说话吗?”

B:“我听得到啊,你能听得到我吗?”

A:“我也能听到你,今天我……”

两次握手:

A:“喂,你听得到我说话吗?”

B:“我听的到啊,你能听得到我吗?”

A:“喂喂,你听得到吗?”

B:“草,我听得到啊!”

A:“你 TM 到底能不能听到我讲话啊!喂?”

B:“……”

四次握手:

A:“喂,你听得到我说话吗?”

B:“我听的到啊,你能听得到我吗?”

A:“我能听到你,你能听到我吗?”

B:“……不想跟傻逼说话”

也就是说,如果通信的双方需要就某个问题达成一致,无论你在消息中包含什么信息,三次通信是理论上最合适的,两次通信并不能保证通信双方建立了可靠的连接,而四次通信就多余了。所以三次握手不是 TCP 本身的要求,而是为了满足「在不可靠信道上可靠地传输信息」这一需求。请注意这里的本质需求,信道不可靠,数据传输要可靠。三次达到了,那后面你想接着握手也好,发数据也好,跟进行可靠信息传输的需求就没关系了。

TCP 头部

上图就是 TCP 协议头部的格式,下面详细说明一下需要了解的信息:

  1. source port(源端口)和 dest port(目的端口):分别占用 16 位,用于区别主机中不同的进程,配合 IP 地址就可以确定主机上的唯一一个 TCP 连接。
  2. sequence Number(序号):用来标识从 TCP 客户端向 TCP 服务端发送的数据流,它表示在这个报文段中的第一个数据字节在数据流中的序号。
  3. acknowledgment Number(确认号):确认号包含发送确认的一端所期望收到的下一个序号,因此,确认序号应是上次成功收到的数据序号 + 1。不过只有当标志位中的 ACK 标志为 1 时该确认序列号的字段才有效。
  4. ACK:此标志表示应答域有效,就是说前面的 TCP 应答号会包含在 TCP 数据包内,为 1 的时候表示应答域有效。
  5. SYN:表示同步序号,用来建立连接。SYN 和 ACK 标志位搭配使用,当连接请求时,SYN = 1,ACK = 0;连接被响应的时候,SYN = 1,ACK = 1;
  6. FIN:表示发送端已经到达数据末尾,也就是说双方的数据传输已经完成,发送 FIN 标志位后,连接将被断开。

具体过程

三次握手

  1. 第一次握手:建立连接。客户端发送连接请求报文段,将 SYN 置 1,seq 为客户端的选择的一个初始序列号 x;然后等待服务器的确认;
  2. 第二次握手:服务器同意建立连接,返回一个报文段,SYN 仍然为 1,seq 设置为服务端的初始序列号 y,ack 设置为 x + 1;
  3. 第三次握手:客户端收到服务器的返回报文段。将 ack 置为 y + 1;向服务器发送 ACK 报文段,发送完毕后,三次握手结束。

那么三次握手的意义何在?

“已失效的连接请求报文段”的产生在这样一种情况下:client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。” ——《计算机网络》谢希仁著

四次挥手

  1. 第一次挥手:客户端设置 sequence number 和 acknowledgment number 向服务端发送一个 FIN 报文段,表示这时已经没有数据要发送给服务端了;
  2. 第二次挥手:服务端收到了客户端发送的 FIN 报文段,向客户端回一个 ACK 报文段,acknowledgment number 为 sequence number + 1;服务端同意你客户端的关闭请求,发送 FIN 报文段;
  3. 第三次挥手:客户端收到服务端发来的 FIN 报文段,向服务端回复 ACK 报文段;此时,客户端进入等待时间,如果重复收到 FIN 报文段,依据可靠传输机制,会重新发送 ACK;
  4. 第四次挥手:服务端收到客户端的 ACK 报文段后,就关闭连接了;若 timeout 之后依然没有回复则证明服务端已经关闭,那么客户端也可以关闭链接了。

那么四次分手又是为何?TCP 是全双工模式,这就意味着,当客户端发出 FIN 报文段时,只是表示客户端已经没有数据要发送给服务端了;但是这个时候客户端还是可以接受来自服务端的数据;

当服务端返回 ACK 报文段时,表示他知道客户端没有数据发送了,但是他还是可以发送给客户端数据;当服务端也发送 FIN 报文段时,表示服务端也没有数据发送了,就会告诉客户端我也没有数据发送给你了,之后就会断开这次 TCP 连接。

参考:

TCP 为什么是三次握手,为什么不是两次或四次?

计算机网络

本文标题: 简谈 TCP 协议的三次握手和四次挥手
最后更新:2017 年 12 月 24 日 - 20:12
本文链接:https://blog.itswincer.com/posts/a8e25856/
本文采用:署名-非商业性使用-禁止演绎 4.0 国际 协议进行许可,阅读 相关说明