您的位置:首页 > 理论基础 > 计算机网络

TCP 情况下,TIME_WAIT 和 CLOSE_WAIT 状态

2011-04-12 21:56 549 查看
By fireworks2@foxmail.com

有关 TCP 下的各个状态转移,认真分析一遍就会对内在机理有个大致了解,这里着重说一下困扰大家最多的两种 WAIT 状态。

1. TIME_WAIT


TIME_WAIT 是主动关闭 TCP 连接的那一方出现的状态,系统会在 TIME_WAIT 状态下等待 2MSL(maximum segment lifetime
)后才能释放连接(端口)。通常约合 4 分钟以内。

进入 TIME_WAIT 状态等待 2MSL 的目的:确保连接可靠地关闭,避免产生套接字混淆(同一个端口对应多个套接字)。

服务器产生大量 TIME_WAIT 的原因:服务器存在大量的主动关闭操作,需关注程序何时会执行主动关闭(如批量清理长期空闲的套接字等操作)。一般我们自己写的服务器进行主动断开连接的不多,除非做了空闲超时之类的管理。

2. CLOSE_WAIT


CLOSE_WAIT 是被动关闭 TCP 连接时产生的,如果收到另一端关闭连接的请求后,本地不关闭相应套接字就会导致本地套接字进入这一状态。如果存在大量的 CLOSE_WAIT,说明客户端并发量大,且服务器未能正常感知客户端的退出,也并未及时 close 这些套接字。

为了尽量避免在单台主机上出现大量这些状态的套接字,大致有以下几种做法:

a. TIME_WAIT——调整一下系统的参数,缩短套接字在这些状态下存活的时间

b. CLOSE_WAIT——设置套接字相关选项,打开KEEP_ALIVE,探测对端的存活情况 (如果不存活,就close;epoll 会返回 IN 事件)

c. 该 close 时就要 close(避免大量 CLOSE_WAIT),不要胡乱 close(避免大量 TIME_WAIT)

PS:

通过 keepalive 可以强制从 close_wait 解救出来套接字,不过如果不进行 close 的话,对应的套接字其实尚未关闭,但此时原来占据的端口已经可用了。在 keepalive 探测到对端已经断开或关闭后,产生的事件为可读,recv返回0个字节。此时即使不 close 掉套接字描述符,端口仍将被释放。因与系统具体实现相关,为了便于移植,还是尽量不用为妙,或者自行在应用层实现一个更通用的心跳功能


具体采用什么办法来解决问题,还得看具体情况。

===
=============== 和TCP相关的一些配置参数==================

linux

cd /proc/sys/net/ipv4/ 可以看到各个网络相关的参数

可以往 /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 = 10

...

然后执行 sysctl -p 使之生效
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: