前面说过,TCP是稳定可靠的传输层协议,稳定体现在需要先建立连接(三次握手)才可以进行通讯。但是当一方想要关闭连接时,如果它一走了之,另一端又怎么知道连接已经关闭了呢,这就会导致另一端仍然保持着维护连接所需要的一切资源而无法释放。

所以TCP在关闭连接时也需要进行类似三次握手之类的流程,以通知双方关闭连接,释放资源。称为四次挥手

四次挥手

关闭一个TCP连接需要进行四次报文交互,任意一端关闭连接时都需要向对端发送报文段。

关闭时发送的报文段中FIN位被置1,表示关闭连接

首先调用close关闭套接字描述符的一方称为主动关闭(以客户端为例),从图中可以看到

  • 客户端发送FIN位被置1的报文段,告知服务器自己已经将连接关闭。此时客户端状态变为FIN_WAIT1(表示发送了一个FIN报文段)
  • 服务器收到客户端发送的FIN报文段后将应答报文段发给客户端。此时服务器状态变为CLOSE_WAIT(表示等待服务器应用程序关闭连接)
  • 客户端收到服务器的应答报文段后状态变为FIN_WAIT2(表示等待服务器发送FIN报文段)
  • 一段时间后服务器应用程序调用read/recv时返回0,得知客户端已经关闭连接,随后向客户端发送FIN被置1的报文段。此时服务器状态变为LAST_ACK(表示等待客户端最后一个应答)
  • 客户端收到服务器的FIN报文段后返回应答报文段。此时客户端状态变为TIME_WAIT
  • 服务器收到客户端的应答报文段后,连接关闭流程结束

如果客户端执行close(全关闭),那么在FIN_WAIT2状态下需要等待对端发送FIN报文段才能够继续关闭,如果迟迟收不到对端的FIN报文段,将可能一直等下去。不过很多TCP实现上都会启动一个定时器,如果规定时间到达后仍然没有收到对端的FIN报文段,就继续关闭

从wireshark中也可以看到连接关闭时的报文段发送情况,为了使结果更为明显,执行的操作步骤为

  • 开启服务器客户端程序
  • 客户端等待0.5秒后关闭连接
  • 服务器应用程序发现客户端关闭后(read/recv返回0),等待1秒后关闭连接

等待0.5秒和1秒的原因是防止延迟ACK的存在使报文段一起发送,对观察结果有影响

从结果可以看出

  • 1-3行是建立连接时的三次握手
  • 4-7依次是客户端关闭连接,服务器发送应答,服务器关闭连接,客户端发送应答

另外,虽然客户端关闭连接后直接结束了进程,但是当服务器发送FIN时仍然能够响应ACK,可见TCP是独立于应用程序管理报文段的接收和发送的

TIME_WAIT状态

在上面连接关闭的状态转换图中可以看到,主动关闭的一方TCP会变为TIME_WAIT状态而不会立即关闭,在测试程序运行结束之后也能够看到(服务器监听端口为9999)

➜  client netstat -ant | grep 9999
tcp        0      0 127.0.0.1:45378         127.0.0.1:9999          TIME_WAIT 

由于主动关闭的是客户端,所以客户端使用的端口45378会变为TIME_WAIT状态。在该状态下的端口不能够被立即使用,这么做的好处是

  • 应对服务器重传的FIN报文段。如果服务器没有接收到最后一个ACK报文,就会重传FIN报文段,因为客户端TCP处在TIME_WAIT状态下,仍保留着连接信息,可以再次发送ACK报文给服务器。而如果客户端TCP直接关闭,那么对于服务器重发的FIN报文会认为是无效的连接,将返回RST报文段
  • 使仍在网络中的报文段消失。防止使用同样端口的新连接建立,使服务器误以为是上一个客户端。假设没有TIME_WAIT状态,上一个客户端关闭后立即有一个新客户端使用相同端口并且立刻向服务器发送报文段(SYN),此时服务器会认为这个报文段是上一个客户端发送的之前没到达但现在刚到达的报文段,由于连接已经关闭,这个报文段将被丢掉

TIME_WAIT时间一般是2倍的报文段最大生存时间(2MSL),MSL的时间根据实现互不相同,常见的有30秒,1分钟不等

此外,TCP也提供了可以复用TIME_WAIT端口的方法,为套接字设置SO_REUSEADDR选项即可

TCP状态变迁图

半关闭

由于TCP是全双工的协议,任意一端都既可写又可读,所以TCP允许某一端执行半关闭操作(shutdown函数),比如只关闭发送数据的通道而保留接收数据的通道。

客户端关闭发送通道实际上就是告诉服务器数据已经发送完了,接下来都不会再发送数据了,但是可以接收数据,服务器可以发过来

而当服务器数据发送完毕后就可以调用close执行全关闭操作了,因为双方都不再发送数据,就意味着连接可以终止了

接下来通过wireshark观察半关闭的报文段发送情况,执行流程为

  • 启动服务器客户端,建立连接
  • 客户端0.5秒后调用::shutdown(fd, ::SHUT_WR)关闭写通道,不再发送数据
  • 服务器得知后(read/recv返回0)等待0.5秒向客户端发送一条数据
  • 服务器1秒后调用close关闭连接
  • 客户端得知后关闭连接

从图中可以看到当一端发送FIN报文段后仍然可以进行数据交互

TCP/IP学习笔记(七)四次挥手相关推荐

  1. TCP/IP学习笔记(四)TCP超时重传及拥塞控制

    TCP是可靠的传输层协议,但这并不意味着一端发送的数据一定可以到达另一端,因为传输过程中遇到的情况是不可控的,很有可能就有某些数据发生丢失,所以"可靠"其实并不可靠. 不过毕竟现如 ...

  2. 【TCP/IP学习笔记1】 C语言讲解

    TCP/IP学习笔记(一) 一. TCP/IP结构:      TCP/IP是一个四层协议,结构如下:      1.应用层:各种应用程序和协议,如Http.FTP等.      2.传输层:TCP和 ...

  3. TCP/IP学习笔记(一)(转载)

    一.TCP/IP结构:      TCP/IP是一个四层协议,结构如下:      1.应用层:各种应用程序和协议,如Http.FTP等.      2.传输层:TCP和UDP      TCP提供一 ...

  4. 在深谈TCP/IP三步握手四步挥手原理及衍生问题—长文解剖IP

    如果对网络工程基础不牢,建议通读<细说OSI七层协议模型及OSI参考模型中的数据封装过程?> 下面就是TCP/IP(Transmission Control Protoco/Interne ...

  5. 再深谈TCP/IP三步握手四步挥手原理及衍生问题—长文解剖IP

    转载地址: https://www.zhoulujun.cn/html/theory/ComputerScienceTechnology/network/2015_0708_65.html 如果对网络 ...

  6. TCP / IP学习笔记(9)-dns域名系统

    TCP / IP学习笔记(9)-dns域名系统 前面已经提到了访问一台机器要靠IP地址和MAC地址,其中,MAC地址可以通过ARP协议得到,所以这对用户是透明的,但是IP地址就不行,无论如何用户都需要 ...

  7. 《图解TCP/IP》笔记(十四)传输层两大协议TCP和UDP

    前言:这是我<图解TCP/IP>笔记系列最后一篇(咕咕咕了将近两个月hh),TCP UDP其实面试的时候经常问到! 目录 传输层的定义: TCP与UDP对比 端口号 通信识别: 确定端口号 ...

  8. TCP/IP学习笔记(一)分层模型概述

    简单来说,协议就是不同计算机之间进行通讯所遵循的标准,只有使用相同协议的计算机之间才可以实现网络通讯.这使得即使两台计算机之间的各种设备不同,只要使用的协议相同,就可以通讯 以两个人对话为例,协议可以 ...

  9. TCP IP学习笔记① 互联网通信过程

    文章目录 一.TCP/IP和OSI模型 二.协议分层 2.1 物理层 2.2 数据链路层 2.2.1 以太网协议 2.2.2 MAC地址 2.2.4 广播 2.3 网际层 2.3.1 IP地址     ...

最新文章

  1. [Eclipse]GEF入门系列(六、添加菜单和工具条)
  2. Python: How to import other Python files
  3. Kubernetes初步了解及入门
  4. cms java垃圾回收_java cms垃圾回收器总结
  5. Mac OS X Leopard 10.5.5 安裝手记 (Dell D830)
  6. AIoT让一个屏有了100种用法
  7. c语言课程设计 性别,【图片】发几个C语言课程设计源代码(恭喜自己当上技术小吧主)【东华理工大学吧】_百度贴吧...
  8. 【做题记录】max-min+1=len 区间计数
  9. markdown-Macdown
  10. 工作71:nexttick使用
  11. win7系统一直反复重启_iPhone7开机白苹果反复重启进不了系统维修过程
  12. ogre研究之第一个程序(一)
  13. jq在html中添加dom元素,使用jQuery添加DOM元素的最佳方法
  14. 【多线程】并发执行指定数量的线程
  15. ubuntu 20.04 DNS 设置
  16. Android进阶笔记12:ListView篇之图片优化
  17. sqlloader 直接路径和常规路径_sqlloader
  18. 通过2048学习自定义view(二) 滑动事件监听 与 事件回调
  19. 总结几款国内外在线的神级抠图工具
  20. 外卖优惠券小程序源码,美团外卖,饿了么外卖红包

热门文章

  1. python如何离线安装第三方模块_扣丁学堂python开发之第三方模块pip离线安装
  2. 如何确定电脑主板坏了_【不良资产 】(第1422期)银行在打包不良资产出售之前,会如何处置不良资产?...
  3. android 原始编译过程,Android编译系统环境初始化过程分析.doc
  4. dell服务器sd卡装系统,DELL服务器通过sd卡安装系统(iDRACUsevFlash).doc
  5. 淘宝2011.9.21校园招聘会笔试题
  6. jquery ajax POST/GET 请求至 ASP.NET WebAPI
  7. iOS Xcode全面剖析
  8. 编码:隐匿在计算机软硬件背后的语言(7)--存储器组织
  9. linux 编译java并打包
  10. SqlHelper详解(转载)