- 8
- 0
- 约1.49万字
- 约 9页
- 2017-06-04 发布于河南
- 举报
close_wait状态和time_wait状态
五事九思 (⼤连Linux主机维护)
⼤连linux维护qq群:287800525
不久前,我的Socket Client程序遇到了⼀个⾮常尴尬的错误。它本来应该在⼀个socket⻓连接上持续不断地
向服务器发送数据,如果socket连接断开,那么程序会⾃动不断地重试建⽴连接。
有⼀天发现程序在不断尝试建⽴连接,但是总是失败。⽤netstat查看,这个程序竟然有上千个socket连接处
于CLOSE_WAIT状态,以⾄于达到了上限,所以⽆法建⽴新的socket连接了。
为什么会这样呢?
它们为什么会都处在CLOSE_WAIT状态呢?
CLOSE_WAIT状态的⽣成原因
⾸先我们知道,如果我们的Client程序处于CLOSE_WAIT状态的话,说明套接字是被动关闭的!
因为如果是Server端主动断掉当前连接的话,那么双⽅关闭这个TCP连接共需要四个packet :
Server FIN Client
Server ACK Client
这时候Server端处于FIN_WAIT_2状态;⽽我们的程序处于CLOSE_WAIT状态。
Server FIN Client
这时Client发送FIN给Server ,Client就置为LAST_ACK状态。
Server ACK Client
Server回应了ACK ,那么Client的套接字才会真正置为CLOSED状态。
我们的程序处于CLOSE_WAIT状态,⽽不是LAST_ACK状态,说明还没有发FIN给Server ,那么可能是在
关闭连接之前还有许多数据要发送或者其他事要做,导致没有发这个FIN packet。
原因知道了,那么为什么不发FIN包呢,难道会在关闭⼰⽅连接前有那么多事情要做吗?
还有⼀个问题,为什么有数千个连接都处于这个状态呢?难道那段时间内,服务器端总是主动拆除我们的
连接吗?
不管怎么样,我们必须防⽌类似情况再度发⽣!
⾸先,我们要防⽌不断开辟新的端⼝,这可以通过设置SO_REUSEADDR套接字选项做到:
重⽤本地地址和端⼝
以前我总是⼀个端⼝不⾏,就换⼀个新的使⽤,所以导致让数千个端⼝进⼊CLOSE_WAIT状态。如果下次
还发⽣这种尴尬状况,我希望加⼀个限定,只是当前这个端⼝处于CLOSE_WAIT状态!
在调⽤
sockConnected = socket(AF_INET, SOCK_STREAM, 0);
之后,我们要设置该套接字的选项来重⽤:
/// 允许重⽤本地地址和端⼝:
/// 这样的好处是,即使socket断了,调⽤前⾯的socket函数也不会占⽤另⼀个,⽽是始终就是⼀个端⼝
/// 这样防⽌socket始终连接不上,那么按照原来的做法,会不断地换端⼝。
int nREUSEADDR = 1;
setsockopt(sockConnected,
SOL_SOCKET,
SO_REUSEADDR,
(const char*)nREUSEADDR,
sizeof(int));
教科书上是这么说的:这样,假如服务器关闭或者退出,造成本地地址和端⼝都处于TIME_WAIT状态,那
么SO_REUSEADDR就显得⾮常有⽤。
也许我们⽆法避免被冻结在CLOSE_WAIT状态永远不出现,但起码可以保证不会占⽤新的端⼝。
其次,我们要设置SO_LINGER套接字选项:
从容关闭还是强⾏关闭?
LINGER是“拖延”的意思。
默认情况下(Win2k) ,SO_DONTLINGER套接字选项的是1;SO_LINGER选项是,linger为{l_onoff :0 ,
l_linger :0}。
如果在发送数据的过程中(send()没有
您可能关注的文档
最近下载
- 《消毒供应质量控制指标(2024年版)》.docx VIP
- 股市主力操盘盘 口摩斯密码(原创内容,侵权必究).pptx
- 2012下半年深圳市机关公开招考公务员职位表.doc VIP
- 国际期刊科技论文写作与发表.PDF VIP
- 科技英语写作讲义.pdf VIP
- 《苹果手机删除的照片如何恢复?苹果最近删除照片恢复.docx VIP
- 水平井完井工艺技术要求,SY_T6-2016.pdf VIP
- SY/T 6270-2017 石油天然气钻采设备固井、压裂管汇的使用与维护.pdf VIP
- 部编版一年级语文下册第六单元测试卷.docx VIP
- 德州职业技术学院单招职业技能测试参考试题库(含答案).docx VIP
原创力文档

文档评论(0)