这是所有与服务器连接的外部 IP 信息列表 , 可以看到第五列是所有的外部 IP 信息 ;
proto: 网络类型:TCP / UDP
Recv-Q:接收缓存字节数
Send-Q:发送缓存字节数
Local Address:本地地址
Foreign Address: 外部状态
State:当前连接状态
查询统计 连接TCP的每个状态数
1.netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
2. netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"t",state[key]}'
序号 | 状态 | 描述 |
1 | LAST_ACK | 正在等待处理的请求数 |
2 | SYN_RECV | 等待接收 |
3 | ESTABLISHED | 正常数据传输状态 |
4 | FIN_WAIT1 | 应用说它已经完成 |
5 | FIN_WAIT2 | 另一边已同意释放 |
6 | TIME_WAIT | 处理完毕,等待超时结束的请求数(表示主动关闭) 产生原因:服务端是主动关闭链接时,等待2MSL时间,约4分钟;主要是防止最后一个ACK丢失。 由于TIME_WAIT 的时间会非常长,因此服务端应尽量减少主动关闭连接 |
7 | CLOSED | 无连接是活动的或正在进行 |
8 | LISTEN | 服务器在等待进入呼叫 |
9 | SYN_RECV | 一个连接请求已经到达,等待确认 |
10 | SYN_SENT | 应用已经开始,打开一个连接 |
11 | ITMED_WAIT | 等待所有分组死掉 |
12 | CLOSING | 两边同时尝试关闭 |
13 | LAST_ACK | 等待所有分组死掉 |
14 | CLOSE_WAIT | 表示被动关闭 被动关闭连接是形成的。根据TCP状态机,服务器端收到客户端发送的FIN,则按照TCP实现发送ACK,因此进入CLOSE_WAIT状态。但如果服务器端不执行close(),就不能由CLOSE_WAIT迁移到LAST_ACK,则系统中会存在很多CLOSE_WAIT状态的连接。此时,可能是系统忙于处理读、写操作,而未将已收到FIN的连接,进行close。此时,recv/read已收到FIN的连接socket,会返回0。 |
注意事项:
由于TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不会被释放。网络服务器程序要同时管理大量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源。
为什么需要 TIME_WAIT 状态?
假设最终的ACK丢失,服务端将重发FIN,客服端必须维护TCP状态信息以便可以重发最终的ACK,否则会发送RST,服务端将认为发生错误。TCP实现必须可靠地终止连接的两个方向(全双工关闭),客服端必须进入 TIME_WAIT 状态,因为客服端可能面 临重发最终ACK的情形。
为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间?
如果 TIME_WAIT 状态保持时间不足够长(比如小于2MSL),第一个连接就正常终止了。第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二个连接。TCP实现必须防止某个连接的重复报文在连接终止后出现,所以让TIME_WAIT状态保持时间足够长(2MSL),连接相应方向上的TCP报文要么完全响应完毕,要么被 丢弃。建立第二个连接的时候,不会混淆。
TIME_WAIT 和CLOSE_WAIT状态socket过多
如果服务器出了异常,百分之八九十都是下面两种情况:
1.服务器保持了大量TIME_WAIT状态
2.服务器保持了大量CLOSE_WAIT状态,简单来说CLOSE_WAIT数目过大是由于被动关闭连接处理不当导致的。
Netstat条件过滤
## 按连接类型条件过滤 tcp 所有连接
netstat -ntu | grep tcp
## 按连接端口条件过滤 8080 所有连接
netstat -ntu | grep 8080
## 按连接主机条件过滤 127.0.0.1 所有连接
netstat -ntu | grep 127.0.0.1
....
## 按照多个条件过滤 可用 egrep 过滤UDP端口或8080端口
netstat -ntu | egrep 'upd|8080'
Netstat 统计某个端口有多少外部连接IP,且每个连接IP连接数
## 截取所有外部连接信息 netstat -ntu | awk '{print $指定列}'
## 因为第5列是外部连接信息,要获取指定的列的信息,将列下标输入即可(从1开始)
netstat -ntu | awk '{print $5}'
##netstat -ntu | grep 网络类型| grep 端口 | awk '{print $5}'
## 搜索TCP 连接 且 端口未8080 的所有外部连接
netstat -ntu | grep tcp | grep 8080| awk '{print $5}'
##只获取外部连接IP信息 | cut -d: -f1
netstat -ntu | grep tcp | grep 8080 | awk '{print $5}' | cut -d: -f1
##去重连接IP 并进行 每个IP统计
netstat -ntu | grep tcp | grep 8080 | awk '{print $5}' | cut -d: -f1 | uniq -c
## 按照 总数进行排序(sort 默认升序 可使用 -nr 进行降序),有连接数大小排序
netstat -ntu | grep tcp | grep 8080 | awk '{print $5}' | cut -d: -f1 | uniq -c |sort -nr
## 按照条件取前(head -5) 或 后(tail -5) 5条
netstat -ntu | grep tcp | grep 8080 | awk '{print $5}' | cut -d: -f1 | uniq -c |sort -nr | head -5