部分内容转自:再谈应用环境下的TIME_WAIT和CLOSE_WAIT - C My Life
- 博客频道 - CSDN.NET
1、TCP连接建立和断开的过程
查看服务器socket状态命令:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 814
CLOSE_WAIT 1
FIN_WAIT1 1
ESTABLISHED 634
SYN_RECV 2
LAST_ACK 1
2、time_wait&close_wait状态
time_wait表示主动关闭,close_wait表示被动关闭。
time_wait状态会保持2MSL(max segment lifetime),主要基于以下两个原因:
1)如果客户端最后回复的ack包丢失,还可以处理服务端重发的fin包,可靠的终止tcp连接。
2)防止新创建的socket读到迟来的报文,保证迟来的tcp报文有足够的时间被识别并丢弃。
3、服务器出现大量time_wait状态
一般可以通过修改/etc/sysctl.conf文件来解决。
net.ipv4.tcp_tw_reuse和net.ipv4.tcp_tw_recycle的开启都是为了回收处于TIME_WAIT状态的资源。
net.ipv4.tcp_fin_timeout这个时间可以减少在异常情况下服务器从FIN-WAIT-2转到TIME_WAIT的时间。
net.ipv4.tcp_keepalive_*一系列参数,是用来设置服务器检测连接存活的相关配置。修改完之后执行/sbin/sysctl -p让参数生效。
4、服务器出现大量的close_wait状态
从上面的图可以看出来,如果一直保持在close_wait状态,那么只有一种情况,就是在对方关闭连接之后服务器程序自己没有进一步发出ack信号。换句话说,就是在对方连接关闭之后,程序里没有检测到,或者程序压根就忘记了这个时候需要关闭连接,于是这个资源就一直被程序占着。所以如果将大量close_wait的解决办法总结为一句话那就是:查代码。因为问题出在服务器程序里头啊。
5、shutdown接口
int close(int fd);
int shutdown(int sockfd, int howto);
close是系统的通用关闭接口,在关闭sock的时候只能同时关闭读写。
shutdown是专为网络编程设计的接口,可以只关闭读或写,howto参数决定接口行为。
SHUT_RD:关闭sockfd上的读。
SHUT_WR:关闭sockfd上的写。
SHUT_RDWR:关闭sockfd上的读和写。
TCP:TCP协议三次握手连接四次握手断开和DOS攻击 - NowOrNever
- 博客频道 - CSDN.NET
TCP&UDP:TCP与UDP的区别 - higirle - 博客园
IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇):blog.csdn.net/historyasamirror/article/details/5778378