TCP是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓的“连接”,其实是客户端和服务器的内存里保存的一份关于对方的信息,如ip地址、端口号等。

一、三次握手

三次握手的过程

TCP 三次握手就好比两个人在街上隔着50米看见了对方,但是因为雾霾等原因不能100%确认,所以要通过招手的方式相互确定对方是否认识自己。

简单的比喻

张三首先向李四招手(syn),李四看到张三向自己招手后,向对方点了点头挤出了一个微笑(ack)。张三看到李四微笑后确认了李四成功辨认出了自己(进入estalished状态)。

但是李四还有点狐疑,向四周看了一看,有没有可能张三是在看别人呢,他也需要确认一下。所以李四也向张三招了招手(syn),张三看到李四向自己招手后知道对方是在寻求自己的确认,于是也点了点头挤出了微笑(ack),李四看到对方的微笑后确认了张三就是在向自己打招呼(进入established状态)。

于是两人加快步伐,走到了一起,相互拥抱。

为什么是三次

过程:张三招手–李四点头微笑–李四招手–张三点头微笑 。其中李四连续进行了2个动作,先是点头微笑(回复对方),然后再次招手(寻求确认),实际上可以将这两个动作合一,招手的同时点头和微笑(syn+ack)。于是四个动作就简化成了三个动作,张三招手–李四点头微笑并招手–张三点头微笑。这就是三次握手的本质,中间的一次动作是两个动作的合并。

图的解释:

  1. client端发送syn字段,请求连接
  2. server端回复acksyn字段字段确定与之连接
  3. client接到确认后进入established已建立状态,并发送ack字段确认对方的连接

为什么要三次握手

“3次握手”的作用就是双方都能明确自己和对方的收、发能力是正常的

  1. 第一次

    客户端发送网络包,服务器收到了。这样服务器得出结论:客户端的发送能力、服务端的接收能力是正常的。

  2. 第二次

    服务端发包,客户端收到了。此时客户端得出结论:服务端的接收、发送能力正常,客户端的接收、发送能力正常

  3. 第三次

    客户端发送的包,服务端收到了。这样服务端就能得出结论:服务端的接收、发送能力正常,客户端的接收、发送能力正常

每次握手确认的能力
| | 客户端 | 服务端 | | ---------------- | ---------- | ---------- | | 第一次(服务器) | 发送 | 接收 | | 第二次(客户端) | 接收、发送 | 接收、发送 | | 第三次(服务端) | 接收、发送 | 接收、发送 |
客户端与服务端能力确认
| 视角 | 客户端接收能力 | 客户端发送能力 | 服务端接收能力 | 服务端发送能力 | | ------ | -------------- | -------------- | -------------- | -------------- | | 客户端 | 二 | 一+二 | 一+二 | 二 | | 服务端 | 二+三 | 一 | 一 | 二+三 |

二、四次断开

四次断开过程

TCP断开链接的过程和建立链接的过程比较类似,只不过中间的两部并不总是会合成一步走,所以它分成了4个动作,张三挥手(fin)——李四伤感地微笑(ack)——李四挥手(fin)——张三伤感地微笑(ack)。

  1. 客户端发送FIN字段,客户端进入fin_wait 状态,服务端进入close_wait状态
  2. 服务端回复ACK字段,客户端进入fin_wait状态
  3. 服务端再次发送FIN字段,服务端并进入last_wait状态
  4. 客户端确认,回复ACK字段,客户端进入time_wait[1]状态,服务端进入关闭状态

为什么是四次

  • 握手

    服务端在LINSTEN状态下,收到建立请求的报文后,把ACKSYN放在一个报文里发送。

  • 断开

    当接收到对方的FIN报文后,仅仅表示对方不在发送数据了,但是还能接收。己方是否关闭发送通道,需要上层应用来决定。


  1. 它是主动关闭的一方在回复完对方的挥手后进入的一个长期状态,这个状态标准的持续时间是4分钟,4分钟后才会进入到closed状态,释放套接字资源。不过在具体实现上这个时间是可以调整的。它就好比主动分手方要承担的责任,是你提出的要分手,你得付出代价。这个后果就是持续4分钟的time_wait状态,不能释放套接字资源(端口),就好比守寡期,这段时间内套接字资源(端口)不得回收利用。 ↩︎