前言
netstat 命令 属于 net-tools package。
备注:这个工具包还有我们经常使用的ifconfig,但是不推荐使用这个工具包了,取而代之的是ss,ip等命令所属的工具包 iproute2 package。
一、netstat简单使用
netstat - Print network connections, routing tables, interface statistics, masquerade connections, and multicast memberships
netstat [address_family_options] [--tcp|-t] [--udp|-u] [--raw|-w]
(1)
--interfaces=iface , -I=iface , -i
Display a table of all network interfaces, or the specified iface.
[root@localhost ~]# netstat -i
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
enp1s0 1500 183897 0 0 0 25748 0 0 0 BMRU
lo 65536 27943 0 0 0 27943 0 0 0 LRU
virbr0 1500 0 0 0 0 0 0 0 0 BMU
该列包括网络接口(Iface)、MTU和一系列接收(RX-)和发送(TX-)的指标:
-OK: Packets transferred successfully
-ERR: Packet errors
-DRP: Packet drops
-OVR: Packet overruns
数据包丢失和溢出(drops and overruns)是网络接口饱和的迹象。
-c(continuous mode)可以与-i一起使用,它每秒打印这些累积计数器,这为计算数据包速率提供了数据:
netstat -i -c
(2)
--statistics , -s
Display summary statistics for each protocol.
只列举了与Linux性能相关的一些TCP统计数据信息,数据来源参考资料。
[root@localhost ~]# netstat -s
Ip:
......
454143446 total packets received
0 forwarded
......
Icmp:
[......]
IcmpMsg:
[......]
Tcp:
......
359286 active connection openings
9463980 passive connection openings
453673963 segments received
922299281 segments sent out
127247 segments retransmitted
......
Udp:
[......]
TcpExt:
......
12252 packets pruned from receive queue because of socket buffer overrun
11727438 delayed acks sent
28248 fast retransmits
805315 packets collapsed in receive queue due to low socket buffer
TCPAutoCorking: 13520259
TCPSynRetrans: 24816
......
输出列出了各种网络统计信息,主要来自 TCP,按协议分组。一些示例统计数据:
转发的数据包与接收的总数据包的比率很高:检查服务器是否应该在转发(路由)数据包。
被动连接打开:可以对其进行监控以显示客户端连接的负载。
重传段与发出段的比率很高:表明网络可能不可靠。
TCPSynRetrans:显示重新传输的 SYN,这可能是由于远程端点因负载而从the listen backlog中丢弃 SYN。
由于套接字缓冲区溢出而从接收队列中删除的数据包:这是网络饱和的标志,如果应用程序有足够的系统资源,可以通过增加套接字缓冲区来修复。
一些tcp配置参数都在该目录下:
ls -l /proc/sys/net/ipv4/
比如:
- TCP 接收缓冲区的大小是受控制的。通常情况下,默认都是使用 net.ipv4.tcp_rmem 来控制缓冲区的大小。可以适当地增大这几个值的默认值,来获取更好的网络性能。
[root@localhost ~]# cat /proc/sys/net/ipv4/tcp_rmem
4096 87380 6291456
rmem有3 个字段:min、default、max。TCP 接收缓冲区大小是在 min 和 max 之间动态调整。
- TCP 发送缓冲区的大小默认是受 net.ipv4.tcp_wmem 来控制:
[root@localhost ~]# cat /proc/sys/net/ipv4/tcp_wmem
4096 16384 4194304
tcp_wmem 中这三个数字的含义分别为 min、default、max。TCP 发送缓冲区的大小会在 min 和 max 之间动态调整,初始的大小是 default,这个动态调整的过程是由内核自动来做的,应用程序无法干预。自动调整的目的,是为了在尽可能少的浪费内存的情况下来满足发包的需要。
(3)
--route , -r
Display the kernel routing tables
等价于:
route
show / manipulate the IP routing table
ip - show / manipulate routing, devices, policy routing and tunnels
route - routing table entry.
ip route
(4)
--groups , -g
Display multicast group membership information for IPv4 and IPv6.
(5)
--numeric , -n
Show numerical addresses instead of trying to determine symbolic host, port or user names.
(6)
--protocol=family , -A
Specifies the address families (perhaps better described as low level protocols) for which connections are to be shown. family is a comma (',') separated list of address family keywords like
inet, inet6, unix, ipx, ax25, netrom, econet, and ddp. This has the same effect as using the --inet|-4, --inet6|-6, --unix|-x, --ipx, --ax25, --netrom, and --ddp options.
The address family inet (Iv4) includes raw, udp, udplite and tcp protocol sockets.
(7)
-p, --program
Show the PID and name of the program to which each socket belongs.
(8)
-l, --listening
Show only listening sockets. (These are omitted by default.)
二、netstat输出说明
[root@localhost ~]# netstat -tnp
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 xx.xx.xx.xxx:22 xx.xx.xx.xx:xxxxx ESTABLISHED 28440/sshd: root@no
tcp 0 0 xx.xx.xx.xxx:22 xx.xx.xx.xx:xxxxx ESTABLISHED 27357/sshd: root@pt
tcp 0 0 xx.xx.xx.xxx:22 xx.xx.xx.xx:xxxxx ESTABLISHED 27361/sshd: root@no
tcp 0 96 xx.xx.xx.xxx:22 xx.xx.xx.xx:xxxxx ESTABLISHED 28436/sshd: root@pt
Proto
The protocol (tcp, udp, udpl, raw) used by the socket.
Recv-Q
Established: The count of bytes not copied by the user program connected to this socket.
Send-Q
Established: The count of bytes not acknowledged by the remote host.
Local Address
Address and port number of the local end of the socket.
Foreign Address
Address and port number of the remote end of the socket.
State
ESTABLISHED
The socket has an established connection.
SYN_SENT
The socket is actively attempting to establish a connection.
SYN_RECV
A connection request has been received from the network.
FIN_WAIT1
The socket is closed, and the connection is shutting down.
FIN_WAIT2
Connection is closed, and the socket is waiting for a shutdown from the remote end.
TIME_WAIT
The socket is waiting after close to handle packets still in the network.
CLOSE The socket is not being used.
CLOSE_WAIT
The remote end has shut down, waiting for the socket to close.
LAST_ACK
The remote end has shut down, and the socket is closed. Waiting for acknowledgement.
LISTEN The socket is listening for incoming connections.
CLOSING
Both sockets are shut down but we still don't have all our data sent.
UNKNOWN
The state of the socket is unknown.
其中三次握手过程设计到的State:
其中四次挥手设计到state:
图片来源于:图解网络
User
The username or the user id (UID) of the owner of the socket.
PID/Program name
Slash-separated pair of the process id (PID) and process name of the process that owns the socket.
Linux内核关于state的定义:
// linux-3.10/include/net/tcp_states.h
/*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
* interface as the means of communication with the user level.
*
* Definitions for the TCP protocol sk_state field.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _LINUX_TCP_STATES_H
#define _LINUX_TCP_STATES_H
enum {
TCP_ESTABLISHED = 1,
TCP_SYN_SENT,
TCP_SYN_RECV,
TCP_FIN_WAIT1,
TCP_FIN_WAIT2,
TCP_TIME_WAIT,
TCP_CLOSE,
TCP_CLOSE_WAIT,
TCP_LAST_ACK,
TCP_LISTEN,
TCP_CLOSING, /* Now a valid state */
TCP_MAX_STATES /* Leave at the end! */
};
#define TCP_STATE_MASK 0xF
#define TCP_ACTION_FIN (1 << 7)
enum {
TCPF_ESTABLISHED = (1 << 1),
TCPF_SYN_SENT = (1 << 2),
TCPF_SYN_RECV = (1 << 3),
TCPF_FIN_WAIT1 = (1 << 4),
TCPF_FIN_WAIT2 = (1 << 5),
TCPF_TIME_WAIT = (1 << 6),
TCPF_CLOSE = (1 << 7),
TCPF_CLOSE_WAIT = (1 << 8),
TCPF_LAST_ACK = (1 << 9),
TCPF_LISTEN = (1 << 10),
TCPF_CLOSING = (1 << 11)
};
#endif /* _LINUX_TCP_STATES_H */
三、netstat数据来源
netstat的显示网络数据的原理通过解析/proc/net/下的文件:
FILES
/etc/services -- The services translation file
/proc -- Mount point for the proc filesystem, which gives access to kernel status information via the following files.
/proc/net/dev -- device information
/proc/net/raw -- raw socket information
/proc/net/tcp -- TCP socket information
/proc/net/udp -- UDP socket information
/proc/net/udplite -- UDPLite socket information
/proc/net/igmp -- IGMP multicast information
/proc/net/unix -- Unix domain socket information
......
我以查看tcp连接为例:
使用strace命令跟踪 netstat -t 过程中调用的open系统调用,然后重定向文件中:
strace -e open netstat -t 2>netstat_log
从结果可以看到 netstat -t 就是通过解析 /proc/net/tcp 文件获取tcp数据来源:
[root@localhost]# cat netstat_log | grep "/proc/net"
open("/proc/net/tcp", O_RDONLY) = 3
open("/proc/net/tcp6", O_RDONLY) = 3
由于/proc/net文件是文本文件,用netstat作为查看tcp临时报告的来源非常方便,只需要awk进行处理。在性能要求高的环境下,监视工具应该使用netlink接口,它以二进制格式传递信息,并避免文本解析的开销,比如ss。
当网络连接数量较多时,netstat解析数据的效率将会变低。现在一般用ss命令来替代netstat。
[root@localhost ~]# time netstat | tail -0
real 0m0.096s
user 0m0.008s
sys 0m0.015s
[root@localhost ~]# time ss | tail -0
real 0m0.004s
user 0m0.001s
sys 0m0.006s
[root@localhost ~]#
用time命令查看可见ss命令比netstat更加高效。
参考资料
Linux 3.10
极客时间:Linux 内核技术实战课
Systems.Performance.Enterprise.and.the.Cloud.2nd.Edition
https://xiaolincoding.com/network/
转载:https://blog.csdn.net/weixin_45030965/article/details/127446952