搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
码创造者
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
【李老师云计算】作业二,大数据开发开发面试书籍
2
RabbitMQ学习笔记(六)——优化RabbitMQ集群_rabbitmq 集群状态api
3
消息中间件---kafka---深入理解kafka_卡夫卡中间键
4
JVM调优之JVM垃圾收集器_jvm调优需要改变垃圾收集器吗
5
Django的语言模板_django模板语言
6
认知科学与人工智能:共同打造个性化智能服务
7
240627_关于CNN中图像维度变化问题
8
开发工具——postman使用教程详解_在线发送post请求工具
9
部署微调框架LLaMA-Factory_llama-factory 微调本地部署
10
Spring框架的介绍和创建
当前位置:
article
> 正文
tcp断开_tcp disconnected
作者:码创造者 | 2024-06-24 22:34:43
赞
踩
tcp disconnected
TCP状态转移要点
TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不 会被释放。网络服务器程序要同时管理大量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源。在众多TCP状态中,最值得 注意的状态有两个:CLOSE_WAIT和TIME_WAIT。
1、LISTENING状态
FTP服务启动后首先处于侦听(LISTENING)状态。
2、ESTABLISHED状态
ESTABLISHED的意思是建立连接。表示两台机器正在通信。
3、CLOSE_WAIT
对方主动关闭连接或者网络异常导致连接中断,这时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来使得连接正确关闭
4、TIME_WAIT
我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT。TCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分 段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。处于TIME_WAIT状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情 况下,尽量不要主动断开连接,以减少TIME_WAIT状态造成的资源浪费。
目前有一种避免TIME_WAIT资源浪费的方法,就是关闭socket的LINGER选项。但这种做法是TCP协议不推荐使用的,在某些情况下这个操作 可能会带来错误。
在连接撤销过程中,有如下四个过程:
1. HOST1上的应用程序关闭己方的连接导致TCP发送一个FIN消息给HOST2。
2. HOST2发送一个确认消息给HOST1,并且HOST2把FIN作为EOF递交给HOST2上的应用程序。
3. 一段时间过后,HOST2上的应用程序关闭它那边的连接,引发一个FIN消息给HOST1。
4. HOST1给HOST2发送一个确认消息,然后HOST2关闭连接并释放资源,然而,HOST1却没有关闭连接,而是进入了TIME_WAIT状态,并为 两个最大段生存时间(2MSL)保留在此状态.
为什么需要time_wait?
1. 因为在第四步的时候,HOST1发送的ACK可能丢失并导致HOST2重新发送FIN消息,TIME_WAIT维护连接状态.
如果执行主动关闭的一方HOST1 不进入到TIME_WAIT状态就关闭连接那会发生什么呢?当重传的FIN消息到达时,因为TCP已经不再有连接的信息了,所以就用RST(重新启动)消 息应答,导致HOST2进入错误的状态而不是有序终止状态,如果发送最后ACK消息的一方处于TIME_WAIT状态并仍然记录着连接的信息,它就可以正 确的响应对等方HOST2的FIN消息了.
2. TIME_WAIT为连接中”离群的段”提供从网络中消失的时间.
考虑一下,如果延迟或者重传段在连接关闭后到达时会发生什么呢?通常情况下,因为TCP仅仅丢弃该数据并响应RST消息,所以这不会造成任何问题。当 RST消息到达发出延时段的主机时,因为该主机也没有记录连接的任何信息,所以它也丢弃该段。然而,如果两个相同主机之间又建立了一个具有相同端口号的新 连接,那么离群的段就可能被看成是新连接的,如果离群的段中数据的任何序列号恰恰在新连接的当前接收窗口中,数据就会被重新接收,其结果就是破坏新连接。
一、TCP连接关闭的几种方式:
1、“正常”关闭:调用close()关闭socket、没close但进程正常结束(当然这是不应该的做法)、进程core掉、在shell 命令行中kill掉进程,都可抽象成“正常”关闭。因为即使core掉,内核也会马上帮应用程序回收(close)socket文件描述符。
“正常”关闭,默认情况下(非默认即设置Linger下面会介绍),关闭端即客户端TCP层会发FIN包,对端即服务器TCP层收到后,回ACK,客户端 进入FIN_WAIT2状态。此时,TCP终止连接的4个分组中服务器应该发的第3个分组FIN包,其TCP层是不会主动发的,只有服务器端socket “正常”关闭,才会发出这个FIN包。至此,客户端进入TIME_WAIT状态。
2、“非”正常关闭:客户端崩溃了,此时肯定发不出FIN包了(当然啦,内核都没机会帮应用程序回收资源了)。这种情况,服务器端有如下两种情 况:
A、服务器send数据,因为客户端已经崩溃,服务器收不到ACK自然会不停的重传。源自
Berkeley的重传机制,重传8次,相对第一次传的15分钟后仍没收到ACK,则返回
ETIMEDOUT或EHOSTUNREAC错误。如果服务器不理会这个错误,再次调用send,则
立马返回Broken Pipe错误。
注:15分钟超时可以在 /proc/sys/net/ipv4/tcp_retries2 中修改
B、 服务器不发任何数据了,那只有靠应用层心跳检测机制或Keepalive,来发觉TCP断连了。
二、SO_LINGER套接口选项
A、l_onoff设置为0,这也是默认情况,函数close()是立即返回的,然后TCP连接双方是通过
FIN、ACK4分组来终止TCP连接的。当然,发送缓冲区还有数据的话,系统将试着将这些数据
发送到对方。
B、l_onoff非0,l_linger设置0,函数close()立即返回,并发送RST终止连接,发送缓冲区的数据丢弃。
C、l_onoff非0,l_linger非0,函数close()不立即返回,而是在(a)发送缓冲区数据发送完并得到确认
(b)l_linger延迟时间到,l_linger时间单位为微妙。两者之一成立时返回。如果在发送缓冲区数据发送
完并被确认前延迟时间到的话,close返回EWOULDBLOCK(或EAGAIN)错误。
三、客户端TCP连接“正常”关闭,服务器的几种情况:
情形 客户端l_onoff设置为0,
“正常”关闭 客户端l_onoff非0,l_linger设置0,“正常”关闭
服务器阻塞模式send,正阻塞在send函数未返回 客户端TCP发送FIN,服务器send函数返回成功(返回字节数是实际拷贝到发送缓冲区的字节数)。客户端发送RST。如果服务器再次调用send,将 返回errno[32]:Broken pipe 客户端TCP发送RST,服务器函数返回成功(返回字节数是实际拷贝到发送缓冲区的字节数)。若服务器再次调用send,则返回 -1,errno[104]:Connection reset by peer。若再次调用send,则返回-1,errno[32]:Broken pipe
服务器空闲 客户端TCP发送FIN,若服务器没理会而调用send,客户端发送RST,send返回-1,errno[32]:Broken pipe 客户端TCP发送RST,若服务器没理会而调用send,send返回-1,errno[104]:Connection reset by peer。若再次调用send,则返回-1,errno[32]:Broken pipe
总之,1、收到对端RST后,仍然调入send(),则返回Connection reset by peer,再次调用send(),则返回Broken pipe
2、收到对端FIN后,仍然调研哪个send(),直接返回Broken pipe
setsockopt 设置 SO_LINGER 选项
此选项指定函数close对面向连接的协议如何操作(如TCP)。内核缺省close操作是立即返回,如果有数据残留在套接口缓冲区中则系统将试着将这些 数据发送给对方。
SO_LINGER选项用来改变此缺省设置。使用如下结构:
struct linger {
int l_onoff; /* 0 = off, nozero = on */
int l_linger; /* linger time */
};
有下列三种情况:
1、设置 l_onoff为0,则该选项关闭,l_linger的值被忽略,等于内核缺省情况,close调用会立即返回给调用者,如果可能将会传输任何未发送的数 据;
2、设置 l_onoff为非0,l_linger为0,则套接口关闭时TCP夭折连接,TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方, 而不是通常的四分组终止序列,这避免了TIME_WAIT状态;
3、设置 l_onoff 为非0,l_linger为非0,当套接口关闭时内核将拖延一段时间(由l_linger决定)。如果套接口缓冲区中仍残留数据,进程将处于睡眠状态,直 到(a)所有数据发送完且被对方确认,之后进行正常的终止序列(描述字访问计数为0)或(b)延迟时间到。此种情况下,应用程序检查close的返回值是 非常重要的,如果在数据发送完并被确认前时间到,close将返回EWOULDBLOCK错误且套接口发送缓冲区中的任何数据都丢失。close的成功返 回仅告诉我们发送的数据(和FIN)已由对方TCP确认,它并不能告诉我们对方应用进程是否已读了数据。如果套接口设为非阻塞的,它将不等待close完 成。
注释:l_linger的单位依赖于实现: 4.4BSD假设其单位是时钟滴答(百分之一秒),但Posix.1g规定单位为秒。
下面的代码是一个使用SO_LINGER选项的例子,使用30秒的超时时限:
#define TRUE 1
#define FALSE 0
int z; /* Status code
*/ int s; /* Socket s */
struct linger so_linger;
...
so_linger.l_onoff = TRUE;
so_linger.l_linger = 30;
z = setsockopt(s,
SOL_SOCKET,
SO_LINGER,
&so_linger,
sizeof so_linger);
if ( z )
perror("setsockopt(2)");
下面的例子显示了如何设置SO_LINGER的值来中止套接口s上的当前连接:
#define TRUE 1
#define FALSE 0
int z; /* Status code */
int s; /* Socket s */
struct linger so_linger;
...
so_linger.l_onoff = TRUE;
so_linger.l_linger = 0;
z = setsockopt(s,
SOL_SOCKET,
SO_LINGER,
&so_linger,
sizeof so_linger);
if ( z )
perror("setsockopt(2)");
close(s); /* Abort connection */
在上面的这个例子中,当调用close函数时,套接口s会立即中止。中止的语义是通过将超 时值设置为0来实现的。
/********** WINDOWS **********/
/* 当连接中断时,需要延迟关闭(linger)以保证所有数据都被传输,所以需要打开SO_LINGER这个选项;
* //注:大致意思就是说SO_LINGER选项用来设置当调用closesocket时是否马上关闭socket;
* linger的结构在/usr/include/linux/socket.h中定义://注:这个结构就是SetSocketOpt中的Data的数据 结构
* struct linger
* {
* int l_onoff; /* Linger active */ //低字节,0和非0,用来表示是否延时关闭socket
* int l_linger; /* How long to linger */ //高字节,延时的时间数,单位为秒
* };
* 如果l_onoff为0,则延迟关闭特性就被取消。
* 如果非零,则允许套接口延迟关闭; l_linger字段则指明延迟关闭的时间
*/
更具体的描述如下:
1、若设置了SO_LINGER(亦即linger结 构中的l_onoff域设为非零),并设置了零超时间隔,则closesocket()不被阻塞立即执行,不论是否有排队数据未发送或未被确认。这种关闭 方式称为“强制”或“失效”关闭,因为套接口的虚电路立即被复位,且丢失了未发送的数据。在远端的recv()调用将以WSAECONNRESET出错。
2、若设置了SO_LINGER并确定了非零的超时间隔,则closesocket()调 用阻塞进程,直到所剩数据发送完毕或超时。这种关闭称为“优雅”或“从容”关闭。请注意如果套接口置为非阻塞且SO_LINGER设为非零超时,则 closesocket()调用将以WSAEWOULDBLOCK错误返回。
3、若在一个流类套接口上设置了SO_DONTLINGER(也就是说将linger结构 的l_onoff域设为零),则closesocket()调用立即返回。但是,如果可能,排队的数据将在套接口关闭前发送。请注意,在这种情况下 WINDOWS套接口实现将在一段不确定的时间内保留套接口以及其他资源,这对于想用所以套接口的应用程序来说有一定影响。
SO_DONTLINGER 若为真,则SO_LINGER选项被禁止。
SO_LINGER 延迟关闭连接 struct linger上面这两个选项影响close行为;
选项 间隔 关闭方式 等待关闭与否
SO_DONTLINGER 不关心 优雅 否
SO_LINGER 零 强制 否
SO_LINGER 非零 优雅 是
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/码创造者/article/detail/754213
推荐阅读
article
25
机器
学习
相关
参考文献
及
推荐
阅读
_
机器
学习
历史
参考文献
...
参考文献
:高等数学第六版上下册,同济大学数学系编;微积分概念发展史,[美] 卡尔·B·波耶 著,唐生 译;概率论与数理统...
赞
踩
article
大
数据
预测
与趋势分析:如何
预测
天气
变化
...
1.背景介绍
大
数据
技术在各个领域的应用不断崛起,
天气
预测
也是其中的一个重要应用。随着人类对环境的关注逐渐加深,
天气
预测
技...
赞
踩
article
通过
前序
遍历
序列
和
中序
遍历
序列
构造
二叉树
_本关任务要求采用
前序
遍历
序列
和
中序
遍历
序列
构造
二叉树
...
输入某
二叉树
的
前序
遍历
和
中序
遍历
的结果,请重建该
二叉树
。假设输入的
前序
遍历
和
中序
遍历
的结果中都不含重复的数字。例如,给出...
赞
踩
article
海康威视工业摄像机MV-
CU120
-
10GC
使用说明_mv-
cu120
-
10gc
说明书
...
注意:若画面为黑,是因为工业相机初始的增益很小,可以打开手电筒测试是否有图像,一般显示为一个白点。搜索“海康威视工业摄像...
赞
踩
article
《
Java
系列-学习相关
》
Java
详细
入门教程
_
java
的
入门教程
...
任何给
java
取名称
的
都叫做标识符栈内存:Stack,连续
的
内存空间,先进后出,主要存放局部变量堆内存:Heap,不连续...
赞
踩
article
Spark
数据
读取保存_
spark
saveastextfile
...
的
数据
读取及
数据
保存可以从两个维度来作区分:文件格式以及文件系统: 类型的文件读都可以用 ,保存使用 2. 读取 jso...
赞
踩
article
可视化
布局
算法
的
框架设计...
写在前面原项目是一个Web项目,采用传统
的
Servlet方式,后台主要完成
的
工作是计算节点
的
坐标,将节点
的
坐标封装成js...
赞
踩
article
超
详细
解读
Transformer
框架
!建议收藏!
_
transform
框架
...
首先我们先对
Transformer
来个直观的认识。
Transformer
出现以前,NLP领域应用基本都是以RNN或LST...
赞
踩
article
8266
与
onenet
平台进行数据交互(基于
MQTT
协议)(附源码)_
onenet
esp
8266
...
运行环境:AiThinker_IDE(Eclipse c/c++)串口助手:AiThinker Serial Tool ...
赞
踩
article
[
ROS
项目]
无人机
仿真
(位置
控制
)_
ros1
控制
无人机
俯仰角
...
无人机
仿真
(位置
控制
)本次项目所用的
仿真
环境是开源的Rotors功能包,初次了解
无人机
的
控制
,也是摸索小白,希望可以起到...
赞
踩
article
基于
Hive
数据
仓库
的教育大
数据
分析平台(伪分布式)_
hive
大
数据
教育平台...
Hive
数据
仓库
的教育大
数据
分析平台_
hive
大
数据
教育平台
hive
大
数据
教育平台 一...
赞
踩
article
DB
-
GPT
:蚂蚁开源
的
Text
-
to
-
SQL
利器!!...
▼最近直播超级多,预约保你有收获—1—AI 原生数据应用时代进入数据3.0时代,大模型和数据库已经成为构建应用程序
的
关键...
赞
踩
article
保姆级
Java
入门练习
教程
,
附
代码
讲解
,
小白零基础入门必备(建议收藏)
_
java
教程
_
java
编程教...
本篇文章带大家搭好环境
,
并体验了控制台打印。下一题是控制台输入
,
大家可以先思考一下
java
编程
教程
带
代码
...
赞
踩
article
模仿
windows
桌面
框选、
重命名
(
vue
3.2)
_
vue
仿pc
桌面
...
{ id: 0, name: "文件1", icon: require("./img/wenjian.png") },{...
赞
踩
article
【转发分享】
基于
单片机
简易
数控
直流
电源
、
基于
单片机
脉冲宽度测量
仿真
系统、
基于
单片机
简易
电饭煲电饭锅仿...
1416
基于
单片机
简易
数控
直流
电源
protues设计-毕 设课设资料(1)
输出
电压:范围0~+9.9V,步进0.1V,纹...
赞
踩
article
C#
测试调用百度
飞桨
PaddleOCRSharp
模块识别图片文字
_
pp
飞桨
c#
...
PaddleOCRSharp
是基于PaddleOCR的C++代码修改并封装的.NET工具类库,支持文本识别、文本检测、基...
赞
踩
article
立创
开源
学习篇
(
一
)
_
力创
开源
...
外面包围的一圈是机壳地,和金属外壳相连与电路板的GND不相连:
(
大疆很多产品有此设计
)
:通过在电路板周围打孔,并连接到机...
赞
踩
article
【
编程语言
】
Python
平台
化
为何
比
Java
差?...
平台
化
指的是软件系统或应用程序能够在不同的硬件和操作系统环境中无缝运行的能力。
平台
化
的系统能够跨越多个环境,提供一致的功...
赞
踩
article
操作系统
原理及
安全
2-
进程
管理
实验
(验证型)_
创建
一个
子
进程
,显示
new
process
(1)...
除了初始
进程
以外,Linux中每个新的
进程
都必须由已经在运行的
进程
来
创建
,这样构成了父
进程
和子
进程
。System是Lin...
赞
踩
article
Hive
UDF
UDTF
UDAF
自定义
函数
详解_
hive
udaf
函数
编写...
Hive
UDF
UDTF
UDAF
自定义
函数
详解_
hive
udaf
函数
编写
hive
udaf
函数
编写 ...
赞
踩
相关标签
大数据
二叉树
数据结构
算法
数码相机
图像处理
java
编程语言
spark
scala
python
机器学习
transformer
深度学习
人工智能
物联网
iot
单片机
oneapi
经验分享
c++
数据仓库
hive
数据分析