Linux网络编程 | TCP状态转换【2MSL】
文章目录
- 一、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】相关推荐
- Linux 网络编程 TCP
(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客 ...
- Linux网络编程——tcp并发服务器(poll实现)
https://blog.csdn.net/lianghe_work/article/details/46535859 想详细彻底地了解poll或看懂下面的代码请参考<Linux网络编程--I/ ...
- linux网络编程tcp和udp基本函数调用过程及如何选择
1. socket编程 1.1 概述 TCP是TCP/IP体系中面向连接的传输层协议,它提供全双工和可靠交付的服务.它采用许多机制来确保端到端结点之间的可靠数据传输,如采用序列号.确认重传.滑动窗口等 ...
- Linux 网络编程——TCP编程
概述 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议. TCP 具有以下特点: 1)电话系统服务模式的抽象 2) ...
- linux网络编程-----TCP连接及相关问题
c/s模型在建立连接时的流程如下 //服务器端 int sockfd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in servaddr; bz ...
- Linux网络编程--TCP中的三次握手和四次挥手
服务器编程和客户端编程的大致流程如下: 三次握手是在客户端中的connect中完成的,具体如下: 那么上述说到的SYN ACK这些是什么东西呢? 上述的截图取自<Linux高性能服务器编 ...
- Linux网络编程——tcp并发服务器(多进程)
https://blog.csdn.net/lianghe_work/article/details/46503895 一.tcp并发服务器概述 一个好的服务器,一般都是并发服务器(同一时刻可以响应多 ...
- Linux网络编程(TCP)
TCP service.c 服务端 #include <stdlib.h> #include <sys/types.h> #include <stdio.h> #i ...
- Linux 网络编程——TCP/IP 数据包格式解析
图中括号中的数字代表的是当前域所占的空间大小,单位是bit位. 黄色的是数据链路层的头部,一共14字节 绿色的部分是IP头部,一般是20字节 紫色部分是TCP头部,一般是20字节 最内部的是数据包内容 ...
最新文章
- js 后台调用前台的JS
- Win7系统下hosts文件修改后无法保存
- KindEditor解决上传视频不能在手机端显示的问题
- 关于设计模式的感悟2
- js获取滚动条距离浏览器顶部,底部的高度,兼容ie和firefox
- 不用掉一根头发!用 Flutter + Dart 快速构建一款绝美移动 App
- spring新注解说明
- 更改Xcode项目名及app名称
- nginx本地代理调试微信登录(window版本)
- 来来来!docker清华源
- SEO人员,如何保持创新思维?
- 对 iOS 14.2 糟糕的音乐控制界面的思考
- 【软件测试】8年资深测试解析,软件测试行业情报,风风雨雨......
- Android软件测试外文文献,软件测试中英文对照外文翻译文献
- Python机器学习基础篇三《无监督学习与预处理》
- CDH 6.3.2 安装(二)
- 广播(Broadcast)的简单用法
- uiautomator2 启动atx
- Simulink自动代码生成2——生成嵌入式代码(generating embedded code)
- Oracle触发器来记录表删除操作简单方法