Chinaunix首页 | 论坛 | 博客
  • 博客访问: 431655
  • 博文数量: 86
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 822
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-25 10:36
文章分类

全部博文(86)

文章存档

2022年(1)

2021年(3)

2020年(1)

2019年(9)

2018年(24)

2017年(20)

2016年(20)

2015年(8)

我的朋友

分类: 网络与安全

2018-03-22 11:48:02

1. 通过 netstat  -anp | grep TIME_WAIT | wc -l 命令查看数量
2. 通过 netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

主动关闭端,需要关注TIME_WAIT状态;
被动关闭端,需要关注CLOSE_WAIT状态;

TIME_WAIT 可以通过修改系统内核参数来缓解: 
vi /etc/sysctl.conf

编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30

然后执行 /sbin/sysctl -p 让参数生效。

CLOSE_WAIT 可以通过修改系统内核参数来解决: 
基本的思想就是要检测出对方已经关闭的socket,然后关闭它。

1.代码需要判断socket,一旦read返回0,断开连接,read返回负,检查一下errno,如果不是AGAIN,也断开连接。(注:在UNP 7.5节的图7.6中,可以看到使用select能够检测出对方发送了FIN,再根据这条规则就可以处理CLOSE_WAIT的连接)
2.给每一个socket设置一个时间戳last_update,每接收或者是发送成功数据,就用当前时间更新这个时间戳。定期检查所有的时间戳,如果时间戳与当前时间差值超过一定的阈值,就关闭这个socket。
3.使用一个Heart-Beat线程,定期向socket发送指定格式的心跳数据包,如果接收到对方的RST报文,说明对方已经关闭了socket,那么我们也关闭这个socket。
4.设置SO_KEEPALIVE选项,并修改内核参数


前提是启用socket的KEEPALIVE机制:
//启用socket连接的KEEPALIVE
int iKeepAlive = 1;
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&iKeepAlive, sizeof(iKeepAlive));
    

echo 120 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 2 > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo 1 > /proc/sys/net/ipv4/tcp_keepalive_probes


除了修改内核参数外,可以使用setsockopt修改socket参数,参考man 7 socket。
    int nKeepAliveProbes = 1;
    int nKeepAliveIntvl = 2;
    int nKeepAliveTime = 120;
setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, (void*)&nKeepAliveProbes, sizeof(nKeepAliveProbes);
setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, (void*)&nKeepAliveIntvl, sizeof(nKeepAliveIntvl);
setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (void*)&nKeepAliveTime, sizeof(nKeepAliveTime);



sysctl -a | grep time | grep wait
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120

状态:描述
CLOSED            无连接是活动的或正在进行
LISTEN             服务器在等待进入呼叫
SYN_RECV        一个连接请求已经到达,等待确认
SYN_SENT        应用已经开始,打开一个连接
ESTABLISHED    正常数据传输状态
FIN_WAIT1        应用说它已经完成
FIN_WAIT2        另一边已同意释放
ITMED_WAIT     等待所有分组死掉
CLOSING           两边同时尝试关闭
TIME_WAIT        另一边已初始化一个释放
LAST_ACK         等待所有分组死掉



参考地址:


阅读(874) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~