文章目录

  • 一、TCP状态转换
    • 1、半关闭
    • 2、2MSL

一、TCP状态转换

CLOSED:表示初始状态。

LISTEN:表示服务器端的某个SOCKET处于监听状态,可连接

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

SYN_RCVD: 表示接收到SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂。此种状态时,当收到客户端的ACK报文后 ,会进入到ESTABLISHED状态。

ESTABLISHED:表示连接已建立

FIN_WAIT_1: 表示等待对方的FIN报文
区别是:

  • FIN_WAIT_1状态是当socket在ESTABLISHED状态时,想主动关闭连接,向对方发送FIN报文,此时该socket进入到FIN_WAIT_1状态。
  • FIN_WAIT_2状态是当对方回应ACK后,该socket进入到FIN_WAIT_2状态,正常情况下,对方应马上回应ACK报文,所以FIN_WAIT_1状态一般较难见到,而FIN_WAIT_2状态可用netstat看到。

FIN_WAIT_2:表示等待对方的FIN报文。主动关闭链接的一方,发出FIN收到ACK以后进入该状态。称之为半连接或半关闭状态。该状态下的socket只能接收数据,不能发。

TIME_WAIT: 表示收到了对方的FIN报文并发送出了ACK报文,等2MSL后即可回到CLOSED可用状态。如果FIN_WAIT_1状态下,收到对方同时带FIN标志ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

CLOSING: 这种状态较特殊,属于一种较罕见的状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的 ACK报文再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文

  • 什么情况下会出现此种情况呢?
    如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

CLOSE_WAIT: 表示在等待关闭。当对方关闭一个SOCKET后发送FIN报文给自己,系统会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,查看是否还有数据发送给对方,如果没有可以close这个SOCKET,发送FIN报文给对方,即关闭连接。所以在CLOSE_WAIT状态下,需要关闭连接。

LAST_ACK: 该状态是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,即可以进入到CLOSED可用状态。

1、半关闭

当TCP链接中A发送FIN请求关闭,B端回应ACK后(A端进入FIN_WAIT_2状态),B没有立即发送FIN给A时,A方处在半链接状态,此时A可以接收B发送的数据,但是A已不能再向B发送数据

close与shutdown的区别

  • 使用close中止一个连接,但它只是减少描述符的引用计数,并不直接关闭连接,只有当描述符的引用计数为0时才关闭连接
  • shutdown不考虑描述符的引用计数,直接关闭描述符。也可选择中止一个方向的连接,只中止读只中止写

注意:

  • 如果有多个进程共享一个套接字,close每被调用一次,计数减1,直到计数为0时,也就是所用进程都调用了close,套接字将被释放。
  • 在多进程中如果一个进程调用了shutdown(sfd, SHUT_RDWR)后,其它的进程将无法进行通信。但,如果一个进程close(sfd)将不会影响到其它进程。

2、2MSL

为什么存在2MSL TIME_WAIT?

4次握手关闭流程更可靠

  • 4次握手的最后一个ACK是由主动关闭方发送出去的,若这个ACK丢失被动关闭方会再次发送一个FIN过来
  • 主动关闭方能够保持一个2MSL的TIME_WAIT状态,则有更大的机会让丢失的ACK被再次发送出去。

防止lost duplicate对后续新建正常链接的传输造成破坏

  • lost uplicate在实际的网络中非常常见,常由于路由器产生故障路径无法收敛导致一个packet在路由器A,B,C之间做类似死循环的跳转。IP头部有个TTL,限制了一个包在网络中的最大跳数,因此这个包有两种命运,要么最后TTL变为0,在网络中消失;要么TTL在变为0之前路由器路径收敛,它凭借剩余的TTL跳数终于到达目的地。但非常可惜的是TCP通过超时重传机制在早些时候发送了一个跟它一模一样的包,并先于它达到了目的地,因此它的命运也就注定被TCP协议栈抛弃

TCP协议栈

TCP是流式的,所有包到达的顺序不一致的,依靠序列号由TCP协议栈做顺序的拼接;假设一个incarnation connection这时收到的seq=1000, 来了一个lost duplicate为seq=1000,len=1000, 则TCP认为这个lost duplicate合法,并存放入了receive buffer,导致传输出现错误。通过一个2MSL TIME_WAIT状态,确保所有的lost duplicate都会消失掉,避免对新连接造成错误。

Linux网络编程 | TCP状态转换【2MSL】相关推荐

  1. Linux 网络编程 TCP

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客 ...

  2. Linux网络编程——tcp并发服务器(poll实现)

    https://blog.csdn.net/lianghe_work/article/details/46535859 想详细彻底地了解poll或看懂下面的代码请参考<Linux网络编程--I/ ...

  3. linux网络编程tcp和udp基本函数调用过程及如何选择

    1. socket编程 1.1 概述 TCP是TCP/IP体系中面向连接的传输层协议,它提供全双工和可靠交付的服务.它采用许多机制来确保端到端结点之间的可靠数据传输,如采用序列号.确认重传.滑动窗口等 ...

  4. Linux 网络编程——TCP编程

    概述 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议. TCP 具有以下特点: 1)电话系统服务模式的抽象 2) ...

  5. linux网络编程-----TCP连接及相关问题

    c/s模型在建立连接时的流程如下 //服务器端 int sockfd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in servaddr; bz ...

  6. Linux网络编程--TCP中的三次握手和四次挥手

    服务器编程和客户端编程的大致流程如下: 三次握手是在客户端中的connect中完成的,具体如下: 那么上述说到的SYN     ACK这些是什么东西呢? 上述的截图取自<Linux高性能服务器编 ...

  7. Linux网络编程——tcp并发服务器(多进程)

    https://blog.csdn.net/lianghe_work/article/details/46503895 一.tcp并发服务器概述 一个好的服务器,一般都是并发服务器(同一时刻可以响应多 ...

  8. Linux网络编程(TCP)

    TCP service.c 服务端 #include <stdlib.h> #include <sys/types.h> #include <stdio.h> #i ...

  9. Linux 网络编程——TCP/IP 数据包格式解析

    图中括号中的数字代表的是当前域所占的空间大小,单位是bit位. 黄色的是数据链路层的头部,一共14字节 绿色的部分是IP头部,一般是20字节 紫色部分是TCP头部,一般是20字节 最内部的是数据包内容 ...

最新文章

  1. js 后台调用前台的JS
  2. Win7系统下hosts文件修改后无法保存
  3. KindEditor解决上传视频不能在手机端显示的问题
  4. 关于设计模式的感悟2
  5. js获取滚动条距离浏览器顶部,底部的高度,兼容ie和firefox
  6. 不用掉一根头发!用 Flutter + Dart 快速构建一款绝美移动 App
  7. spring新注解说明
  8. 更改Xcode项目名及app名称
  9. nginx本地代理调试微信登录(window版本)
  10. 来来来!docker清华源
  11. SEO人员,如何保持创新思维?
  12. 对 iOS 14.2 糟糕的音乐控制界面的思考
  13. 【软件测试】8年资深测试解析,软件测试行业情报,风风雨雨......
  14. Android软件测试外文文献,软件测试中英文对照外文翻译文献
  15. Python机器学习基础篇三《无监督学习与预处理》
  16. CDH 6.3.2 安装(二)
  17. 广播(Broadcast)的简单用法
  18. uiautomator2 启动atx
  19. Simulink自动代码生成2——生成嵌入式代码(generating embedded code)
  20. Oracle触发器来记录表删除操作简单方法

热门文章

  1. Java截取字符串的常见方法
  2. STM32F103C8 监控室内湿度温度
  3. 【Linux】Linux之DNS查询、设置及测试可用性
  4. 物联网开发实战解读 何为杀手级应用?
  5. 超声图像和乳房X光筛查的区别
  6. 我ps制作的html文件alt标记文字,如何在PS中制作我的2016宣言的字体?
  7. oppo如何更新android版本,OPPO新系统跨版本更新,开启全新Android时代
  8. R9000P 混合模式 system持续占用cpu 解决
  9. 关于springboot 多个配置文件的配置
  10. Altium Designer PCB生产gerber文件教程