1、 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

全双工通信。
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

2、 为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?

<2020_05>补充

  1. 保证tcp可靠终止连接
  2. 保证迟来的或重发的tcp报文有足够的时间被识别或者丢弃
    这是因为:虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样);
    但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文,并保证于此。
    <2020_05>原因2:在linux系统一个tcp端口不能被打开两次以上,如果当前端口处于time_wait状态,那么新链接无法建立,而如果不存在time_wait,新的链接可能会接收到原来链接重发或者迟到的数据(比如上一个链接最后的ack没有被server接收到,那么新的链接建立,反而接收到了,server要发给上一个client的报文)

<2020_05>如果出现了time_wait怎么处理

在实际工作中没有出现这样的问题,因为事先已经将机器优化过了,而不是除了time_wait的问题之后才进行优化。
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。

经典的两张图

建立连接协议(三次握手)

  • 客户端发送一个带SYN标志的TCP报文到服务器。这是三次握手过程中的报文1。

  • 服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN标志。因此它表示对刚才客户端SYN报文的回应;同时又标志SYN给客户端,询问客户端是否准备好进行数据通讯。

  • 客户必须再次回应服务段一个ACK报文,这是报文段3。

连接终止协议(四次握手)

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

各种状态详解

CLOSED:

这个没什么好说的了,表示初始状态。

LISTEN:

这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。

SYN_RCVD:

这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。

SYN_SENT:

这个状态与SYN_RCVD遥相呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。

ESTABLISHED:

这个容易理解了,表示连接已经建立了。

FIN_WAIT_1:

这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。

而这两种状态的区别是:

FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。

FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。

TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。

如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

注:MSL(最大分段生存期)指明TCP报文在Internet上最长生存时间,每个具体的TCP实现都必须选择一个确定的MSL值.RFC 1122建议是2分钟,但BSD传统实现采用了30秒.TIME_WAIT 状态最大保持时间是2 * MSL,也就是1-4分钟.

CLOSING:

这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

CLOSE_WAIT:

这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。

LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。

最后有2个问题的回答,我自己分析后的结论(不一定保证100%正确)

对原作者文章,进行了重新排版,和部分错别字校正。
但未联系到原作者,如有侵权可联系我删除文章
http://blog.sina.com.cn/s/blog_8e5d24890102w9yi.html

TCP三次挥手四次握手(面试总结)相关推荐

  1. TCP三次挥手四次握手

    三次握手: 客户端发起: 1.向服务器端发送报文SYN=1,ACK=0;客户端进入SYN-SEND状态. 2.服务端收到SYN=1,ACK=0的请求报文,向客户端返回确认报文SYN=1,ACK=1,服 ...

  2. 由一次线上故障来理解下 TCP 三握、四挥 Java 堆栈分析到源码的探秘

    本文导读: 生产故障场景介绍 TCP 建连三次握手过程 TCP 断连四次挥手过程 结合 Java 堆栈剖析源码 再从堆栈中找到"罪魁祸首" 问题优化方案总结 1.生产故障场景介绍 ...

  3. TCP断开连接的四次握手

    过程 HostA发送一条请求消息,携带序列号seq=100. HostB收到消息回复确认消息携带序列号 seq=300,确认信息ack等于101(101是HostA发送的seq+1) 第1次握手:发送 ...

  4. TCP两次挥手,你见过吗?那四次握手呢?

    我们都知道,TCP是个面向连接的.可靠的.基于字节流的传输层通信协议. 那这里面提到的"面向连接",意味着需要 建立连接,使用连接,释放连接. 建立连接是指我们熟知的TCP三次握手 ...

  5. 活久见!TCP两次挥手,你见过吗?那四次握手呢?

    文章持续更新,可以微信搜一搜「小白debug」第一时间阅读,回复[教程]获golang免费视频教程.本文已经收录在GitHub https://github.com/xiaobaiTech/golan ...

  6. TCP三次握手和四次挥手抓包详解

    这是我在ensp上搭建的小实验,并通过Wireshark抓包观察TCP握手过全过程: 服务器配置 图2 客户端访问 图3 抓包观察 三次握手 图4 1)第一次握手 TCP 协议规定,SYN 置 1 的 ...

  7. TCP四次挥手不同情况的研究(正常状态,三次挥手,以及CLOSING和RST)

    文章目录 TCP四次挥手不同情况的研究 1.新手加油站 1.1 TCP四次握手流程图 1.2 TCP头部 1.3 四次握手流程详解 2.针对挥手不同情况的实验和研究 2.1 正常情况 2.2 三次挥手 ...

  8. TCP/IP 和 TCP/IP的 三/四次握手

    什么是TCP/IP 首先来说,TCP/IP协议是浏览器与服务器链接因特网的协议.浏览器使用TCP/IP协议进入服务器,服务器使用TCP/IP协议来发送HTML文件到浏览器. TCP/IP的作用 TCP ...

  9. TCP 四次挥手,可以变成三次挥手吗?

    作者:小林coding 计算机八股文网站:https://xiaolincoding.com 大家好,我是小林. 虽然我们在学习 TCP 挥手时,学到的是需要四次来完成 TCP 挥手,但是在一些情况下 ...

最新文章

  1. 太卷了!人大附中「内卷」到了美国?华裔家长抗议中国学生持F1签证抢占美国IMO名额...
  2. [转]Hadoop家族学习路线图
  3. 如何解决:Android中 Error generating final archive: Debug Certificate expired on 10/09/18 16:30 的错误...
  4. Zookeeper的命令
  5. 06 事件处理函数绑定与事件对象
  6. 服务器上装filezilla server后,本地的ftp客户端连接不上去
  7. js常用方法,JS实用方法,jq获得文件后缀,解析window。location,解析URL参数
  8. STM32工作笔记0022---STM32F1开发版 GPIO口工作原理
  9. maven下载,安装与eclipse中maven配置
  10. 8、第六 -面向对象高级语法-异常处理
  11. Apache-Shiro-会话管理
  12. ipixsoft swf to html5 converter,iPixSoft SWF to Video Converter
  13. Building and Securing RESTful APIs in ASP.NET Core 在ASP.NET Core中构建安全的RESTful API Lynda课程中文字幕
  14. Clouda框架开发留言板实例
  15. pack_padded_sequence,pad_packed_sequence
  16. 论文阅读笔记《Meta-Learning with Memory-Augmented Neural Networks》
  17. 苹果系统安装Java开发环境JDK
  18. [悦读] 让听得见炮声的人来决策——《赋能》读书笔记
  19. 双十一特辑:Python采集商品数据,实时了解商品价格
  20. 离散数学笔记_第一章:逻辑和证明(1)

热门文章

  1. 使用html css js实现计算器
  2. python函数-函数进阶
  3. 【UVA 10816】 Travel in Desert (最小瓶颈树+最短路)
  4. 关于eclipse的indigo版中文注释时字体太小的问题(转)
  5. 非常好的在网页中显示pdf的方法
  6. 虚拟机照样飞速跑Windows Server2008
  7. 小数前的0在html不显示,jsp小数显示问题 例如 我在oracle 数据库中查询出来的是 0.01 但是在jsp页面上就显示成 .01 没有前面的0...
  8. 易语言自定义数据类型转c,一步一步跟我学易语言之自定义数据类型
  9. 液压支架销轴力学计算分析研究_基于RFID射频精准定位的智能开采研究与应用...
  10. python文件管理包_Python标准库04 文件管理 (部分os包,shutil包)