netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

会得到类似下面的结果,具体数字会有所不同:

LAST_ACK 1
SYN_RECV 14
ESTABLISHED 79
FIN_WAIT1 28
FIN_WAIT2 3
CLOSING 5
TIME_WAIT 1669

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

也就是说,这条命令可以把当前系统的网络连接状态分类汇总。

下面解释一下为啥要这样写:

一个简单的管道符连接了netstat和awk命令。

------------------------------------------------------------------

每个TCP报文在网络内的最长时间,就称为MSL(Maximum Segment Lifetime),它的作用和IP数据包的TTL类似。

RFC793指出,MSL的值是2分钟,但是在实际的实现中,常用的值有以下三种:30秒,1分钟,2分钟。

注意一个问题,进入TIME_WAIT状态的一般情况下是客户端,大多数服务器端一般执行被动关闭,不会进入TIME_WAIT状态,当在服务

器端关闭某个服务再重新启动时,它是会进入TIME_WAIT状态的。

举例:
1.客户端连接服务器的80服务,这时客户端会启用一个本地的端口访问服务器的80,访问完成后关闭此连接,立刻再次访问服务器的

80,这时客户端会启用另一个本地的端口,而不是刚才使用的那个本地端口。原因就是刚才的那个连接还处于TIME_WAIT状态。
2.客户端连接服务器的80服务,这时服务器关闭80端口,立即再次重启80端口的服务,这时可能不会成功启动,原因也是服务器的连

接还处于TIME_WAIT状态。

检查net.ipv4.tcp_tw当前值,将当前的值更改为1分钟:
[root@aaa1 ~]# sysctl -a|grep net.ipv4.tcp_tw
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_tw_recycle = 0
[root@aaa1 ~]#

vi /etc/sysctl
增加或修改net.ipv4.tcp_tw值:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

使内核参数生效:
[root@aaa1 ~]# sysctl -p

[root@aaa1 ~]# sysctl -a|grep net.ipv4.tcp_tw
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

用netstat再观察正常

这里解决问题的关键是如何能够重复利用time_wait的值,我们可以设置时检查一下time和wait的值
#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

问一下TIME_WAIT有什么问题,是闲置而且内存不回收吗?

是的,这样的现象实际是正常的,有时和访问量大有关,设置这两个参数: reuse是表示是否允许重新应用处于TIME-WAIT状态的

socket用于新的TCP连接; recyse是加速TIME-WAIT sockets回收

Q: 我正在写一个unix server程序,不是daemon,经常需要在命令行上重启它,绝大 
多数时候工作正常,但是某些时候会报告"bind: address in use",于是重启失 
败。

A: Andrew Gierth 
server程序总是应该在调用bind()之前设置SO_REUSEADDR套接字选项。至于 
TIME_WAIT状态,你无法避免,那是TCP协议的一部分。

Q: 如何避免等待60秒之后才能重启服务

A: Erik Max Francis

使用setsockopt,比如

-------------------------------------------------------------------------- 
int option = 1;

if ( setsockopt ( masterSocket, SOL_SOCKET, SO_REUSEADDR, &option, 
sizeof( option ) ) < 0 ) 

die( "setsockopt" ); 

--------------------------------------------------------------------------

Q: 编写 TCP/SOCK_STREAM 服务程序时,SO_REUSEADDR到底什么意思?

A: 这个套接字选项通知内核,如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用 
端口。如果端口忙,而TCP状态位于其他状态,重用端口时依旧得到一个错误信息, 
指明"地址已经使用中"。如果你的服务程序停止后想立即重启,而新套接字依旧 
使用同一端口,此时 SO_REUSEADDR 选项非常有用。必须意识到,此时任何非期 
望数据到达,都可能导致服务程序反应混乱,不过这只是一种可能,事实上很不 
可能。

一个套接字由相关五元组构成,协议、本地地址、本地端口、远程地址、远程端 
口。SO_REUSEADDR 仅仅表示可以重用本地本地地址、本地端口,整个相关五元组 
还是唯一确定的。所以,重启后的服务程序有可能收到非期望数据。必须慎重使 
用 SO_REUSEADDR 选项。

Q: 在客户机/服务器编程中(TCP/SOCK_STREAM),如何理解TCP自动机 TIME_WAIT 状 
态?

A:   MSL(最大分段生存期)指明TCP报文在Internet上最长生存时间,每个具体的TCP实现 
都必须选择一个确定的MSL值。RFC 1122建议是2分钟,但BSD传统实现采用了30秒。

TIME_WAIT 状态最大保持时间是2 * MSL,也就是1-4分钟。

IP头部有一个TTL,最大值255。尽管TTL的单位不是秒(根本和时间无关),我们仍需 
假设,TTL为255的TCP报文在Internet上生存时间不能超过MSL。

TCP报文在传送过程中可能因为路由故障被迫缓冲延迟、选择非最优路径等等,结果 
发送方TCP机制开始超时重传。前一个TCP报文可以称为"漫游TCP重复报文",后一个 
TCP报文可以称为"超时重传TCP重复报文",作为面向连接的可靠协议,TCP实现必须 
正确处理这种重复报文,因为二者可能最终都到达。

一个通常的TCP连接终止可以用图描述如下:

client server 
FIN M 
close -----------------> (被动关闭) 
ACK M+1 
<----------------- 
FIN N 
<----------------- close 
ACK N+1 
----------------->

为什么需要 TIME_WAIT 状态?

假设最终的ACK丢失,server将重发FIN,client必须维护TCP状态信息以便可以重发 
最终的ACK,否则会发送RST,结果server认为发生错误。TCP实现必须可靠地终止连 
接的两个方向(全双工关闭),client必须进入 TIME_WAIT 状态,因为client可能面 
临重发最终ACK的情形。


scz 2001-08-31 13:28

先调用close()的一方会进入TIME_WAIT状态 
}

此外,考虑一种情况,TCP实现可能面临先后两个同样的相关五元组。如果前一个连 
接处在 TIME_WAIT 状态,而允许另一个拥有相同相关五元组的连接出现,可能处理 
TCP报文时,两个连接互相干扰。使用 SO_REUSEADDR 选项就需要考虑这种情况。

为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间?

如果 TIME_WAIT 状态保持时间不足够长(比如小于2MSL),第一个连接就正常终止了。 
第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二 
个连接。TCP实现必须防止某个连接的重复报文在连接终止后出现,所以让TIME_WAIT 
状态保持时间足够长(2MSL),连接相应方向上的TCP报文要么完全响应完毕,要么被 
丢弃。建立第二个连接的时候,不会混淆。

A: 小四

在Solaris 7下有内核参数对应 TIME_WAIT 状态保持时间

# ndd -get /dev/tcp tcp_time_wait_interval 
240000 
# ndd -set /dev/tcp tcp_time_wait_interval 1000

缺省设置是240000ms,也就是4分钟。如果用ndd修改这个值,最小只能设置到1000ms, 
也就是1秒。显然内核做了限制,需要Kernel Hacking。

# echo "tcp_param_arr/W 0t0" | adb -kw /dev/ksyms /dev/mem 
physmem 3b72 
tcp_param_arr: 0x3e8 = 0x0 
# ndd -set /dev/tcp tcp_time_wait_interval 0

我不知道这样做有什么灾难性后果,参看<>的声明。

Q: TIME_WAIT 状态保持时间为0会有什么灾难性后果?在普遍的现实应用中,好象也 
就是服务器不稳定点,不见得有什么灾难性后果吧?

D: rain@bbs.whnet.edu.cn

Linux 内核源码 /usr/src/linux/include/net/tcp.h 中

#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to successfully 
* close the socket, about 60 seconds */

最好不要改为0,改成1。端口分配是从上一次分配的端口号+1开始分配的,所以一般 
不会有什么问题。端口分配算法在tcp_ipv4.c中tcp_v4_get_port中。

二、服务器出现TIME_WAIT状态

到此为止,都是从内核上修改保持TIME_WAIT状态的时间参数来保证正确的进行,一般情况下出现TIME_WAIT状态的都是客户端,在业务逻辑中尽量让客户端主动关闭连接,这样也就将TIME_WAIT变相的转载了。但是在有些业务中必须让服务器主动关闭连接。

对于基于TCP的HTTP协议,关闭TCP连接的是Server端,这样,Server端会进入TIME_WAIT状态,可想而知,对于访问量大的Web Server,会存在大量的TIME_WAIT状态,假如server一秒钟接收1000个请求,那么就会积压240*1000=240,000个TIME_WAIT的记录,维护这些状态给Server带来负担。当然现代操作系统都会用快速的查找算法来管理这些TIME_WAIT,所以对于新的TCP连接请求,判断是否hit中一个TIME_WAIT不会太费时间,但是有这么多状态要维护总是不好。

HTTP协议1.1版规定default行为是Keep-Alive,也就是会重用TCP连接传输多个request/response,一个主要原因就是发现了这个问题。还有一个方法减缓TIME_WAIT压力就是把系统的2*MSL时间减少,因为240秒的时间实在是忒长了点,对于Windows,修改注册表,在HKEY_LOCAL_MACHINE\ SYSTEM\CurrentControlSet\Services\ Tcpip\Parameters上添加一个DWORD类型的值TcpTimedWaitDelay,一般认为不要少于60,不然可能会有麻烦。

对于大型的服务,一台server搞不定,需要一个LB(Load Balancer)把流量分配到若干后端服务器上,如果这个LB是以NAT方式工作的话,可能会带来问题。假如所有从LB到后端Server的IP包的source address都是一样的(LB的对内地址),那么LB到后端Server的TCP连接会受限制,因为频繁的TCP连接建立和关闭,会在server上留下TIME_WAIT状态,而且这些状态对应的remote address都是LB的,LB的source port撑死也就60000多个(2^16=65536,1~1023是保留端口,还有一些其他端口缺省也不会用),每个LB上的端口一旦进入Server的TIME_WAIT黑名单,就有240秒不能再用来建立和Server的连接,这样LB和Server最多也就能支持300个左右的连接。如果没有LB,不会有这个问题,因为这样server看到的remote address是internet上广阔无垠的集合,对每个address,60000多个port实在是够用了。

一开始我觉得用上LB会很大程度上限制TCP的连接数,但是实验表明没这回事,LB后面的一台Windows Server 2003每秒处理请求数照样达到了600个,难道TIME_WAIT状态没起作用?用Net Monitor和netstat观察后发现,Server和LB的XXXX端口之间的连接进入TIME_WAIT状态后,再来一个LB的XXXX端口的SYN包,Server照样接收处理了,而是想像的那样被drop掉了。翻书,从书堆里面找出覆满尘土的大学时代买的《UNIX Network Programming, Volume 1, Second Edition: Networking APIs: Sockets and XTI》,中间提到一句,对于BSD-derived实现,只要SYN的sequence number比上一次关闭时的最大sequence number还要大,那么TIME_WAIT状态一样接受这个SYN,难不成Windows也算BSD-derived?有了这点线索和关键字(BSD),找到这个post,在NT4.0的时候,还是和BSD-derived不一样的,不过Windows Server 2003已经是NT5.2了,也许有点差别了。

做个试验,用Socket API编一个Client端,每次都Bind到本地一个端口比如2345,重复的建立TCP连接往一个Server发送Keep-Alive=false的HTTP请求,Windows的实现让sequence number不断的增长,所以虽然Server对于Client的2345端口连接保持TIME_WAIT状态,但是总是能够接受新的请求,不会拒绝。那如果SYN的Sequence Number变小会怎么样呢?同样用Socket API,不过这次用Raw IP,发送一个小sequence number的SYN包过去,Net Monitor里面看到,这个SYN被Server接收后如泥牛如海,一点反应没有,被drop掉了。

按照书上的说法,BSD-derived和Windows Server 2003的做法有安全隐患,不过至少这样至少不会出现TIME_WAIT阻止TCP请求的问题,当然,客户端要配合,保证不同TCP连接的sequence number要上涨不要下降。

Linux 查看tcp 请求 中 的各个 状态 数据 ,如timewait相关推荐

  1. 查看tcp 请求中的各个状态数据

    查看tcp请求中的各个状态数据 文章目录 查看tcp请求中的各个状态数据 查看tcp请求中的各个状态数据,如timewait netstat -n |awk '/^tcp/ {++S[$NF]} EN ...

  2. 请解释一下http请求中的304状态码的含义

    请解释一下http请求中的304状态码的含义 304 未被修改. 自从上次请求后,请求的网页未被修改过.服务器返回此响应时,不会返回网页内容. 如果网页自请求者上次请求后再也没有更改过,你应将服务器配 ...

  3. (POST请求中的三种数据请求格式.application/x-www-form-urlencoded和multipart/form-data和application/json)

    (POST请求中的三种数据请求格式.application/x-www-form-urlencoded和multipart/form-data和application/json) applicatio ...

  4. linux查看tcp连接状态_Linux使用lsof查看打开的文件和网络连接

    lsof是List Open Files的缩写.顾名思义,它用来查看系统中进程打开了哪些文件:因为Linux几乎所有的设备都可以看成是文件,所以lsof经常也可以用来查看管道,sockets的使用状态 ...

  5. aria2百度网盘 http返回头无效_接口测试第10期:Fiddler中查看HTTP请求中的状态码...

    关注后回复[软件测试]查看更多上期介绍了常见的HTTP请求方法,get请求.post请求,今天介绍HTTP请求中的状态码,以后也能分辨出哪些状态码是表示客户端错误,哪些是服务器错误.状态码在Fiddl ...

  6. linux查看tcp连接日志,linux下tcp状态是从哪查出来的

    linux中,各种tcp连接的状态存储在 /proc/net/tcp 文件中 其中st列就是tcp的各种状态,那么这个值代表什么意思呢? 有网友从内核源码里找到了这个 enum { TCP_ESTAB ...

  7. linux查看 tcp连接对应的程序,轻轻松松查看TCP连接及发起程序

    引子: Windows的mspaint(就是画图)程序未知原因崩溃了,提示用户是否将发送错误报告(Windows7的错误报告服务程序是WerFault.exe)给Microsoft Corporati ...

  8. TCP程序中发送和接收数据

    这里我们来探讨一下在网络编程过程中,有关read/write 或者send/recv的使用细节.这里有关常用的阻塞/非阻塞的解释在网上有很多很好的例子,这里就不说了,还有errno ==EAGAIN ...

  9. linux查看tcp连接状态

    netstat -an |grep tcp   查看所有tcp连接包括LISTEN状态 netstat -an |grep ESTABLISHED   查看所有正在连接中的tcp连接 如果需要统计tc ...

最新文章

  1. LeetCode刷题记录9——58. Length of Last Word(easy)
  2. MSSQL - 通用存储过程
  3. SQL创建表格——手写代码
  4. 计算机网络管理员demo,计算机网络试题demo
  5. 写了4年博客,我终于也出了一本书。
  6. OpenShift 4 - 用Compliance Operator对OpenShift进行安全合规扫描
  7. 巧解汽车冬季病 启动无力别“轰油”热车
  8. php基础知识(2),PHP基础知识2
  9. 亲测可用小米刷旧版开发版固件,刷入华硕、潘多拉固件
  10. ubuntu vmplayer安装vmtool
  11. EasyDarwin测试
  12. 免费谷歌学术、知网、维普、scihub镜像
  13. 如何清理废弃pv和其对应的文件夹
  14. SiteSucker Mac版(整站下载工具)中文版
  15. 实现进程互斥需要遵循的原则
  16. NLP 2.9 深度学习与神经网络
  17. swper_swipe和swiper的区别
  18. Python0019 音频处理(二).wav文件
  19. QT5.9用自定义字体修改qlabel字体、大小以及颜色
  20. 雷电三接口有什么用_三坐标中的矢量是干什么用的?

热门文章

  1. java循环语句的四要素如何设置_JAVA 基础4-语句与方法
  2. 整理CSCD和CSD双检期刊
  3. android listview预加载动画,Android开发Activity页面预加载
  4. 电容式触摸芯片的工作原理
  5. DFT1. OCC电路浅析
  6. 【小白做科研( 九 )】炼丹小记
  7. 微信支付接口配置教程(下)
  8. 【已解决】Html Webpack Plugin Error;html-withimg-loader无法正常解析html内的img
  9. 基础篇:6.11)通用公差规则
  10. 24小时从0到1开发阴阳师小程序 1