套接字是什么?
我们先来想一下,线程之间通信我们都知道,比如Java中不同线程可以访问同一个堆内存,自然也就可以方便的交互数据,那么进程之间应该如何通信呢?进程之间要互相传输数据应该怎么办呢?
线程之间通信也有很多种方式比如: 管道pipe、共享存储、信号量、套接字(Socket)等等。
其中一种方式就是Socket,套接字(Socket)是一个抽象的概念,Socket可以看成是两个应用程序进行通信时,各自通信连接中的端点,是一个逻辑上的概念,Socket不仅仅可以跨进程通信,还可以跨机器通信。
套接字有很多种类,比如Internet Socket、Unix Domain Socket、X.25 套接字
我们比较常用的就是Internet Socket,既可以用于同一台主机的进程间通信,也可以用于不同主机不同进程间的通信
不过在本机上Unix Domain Socket的性能更快,并且和TCP一样都是可靠的协议,所以同一台主机中Unix Domain Socket使用的也比较多。
netstat命令简介
netstat
命令用于显示各种网络相关信息,如网络连接,路由表,接口状态等等
当我们执行netstat
后,输出结果为
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:cruise-diags localhost:38011 ESTABLISHED
tcp 0 0 sd01:49669 sd01:8780 TIME_WAIT
tcp 0 0 sd01:38577 sd01:8669 TIME_WAIT
tcp 0 0 sd01:38560 sd01:8669 TIME_WAIT
tcp 0 0 sd01:51406 sd01:8103 TIME_WAIT
tcp 0 0 localhost:cruise-diags localhost:38008 ESTABLISHED
tcp 0 0 localhost:cruise-diags localhost:37996 ESTABLISHED
.....
.....
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ] DGRAM 12296 /run/systemd/notify
unix 6 [ ] DGRAM 12310 /run/systemd/journal/socket
unix 9 [ ] DGRAM 12312 /dev/log
unix 2 [ ] DGRAM 11339 /run/systemd/shutdownd
unix 2 [ ] DGRAM 1116652626 /run/systemd/cgroups-agent
unix 3 [ ] STREAM CONNECTED 14048
可以看出,netstat
的输出结果可以分为两部分
- Active Internet connections,称为活动的网络连接,包括TCP、UDP、UDPLite、raw
- Proto: 使用的协议
- Recv-Q: Established和Listening状态下有不同的含义
- Established: 表示套接字缓冲还没有被应用程序取走的字节数(接收队列的长度)
- Listening: 全连接队列的长度(完成三次握手后的连接就叫全连接)
- Send-Q
- Established: 发送后远程未确认的字节数(发送队列的长度)
- Listening: 全连接队列的最大长度
- Local Address: 本地的地址和端口
- Foreign Address: 远程的地址和端口
- State: 套接字的状态,由于row、UDP和UDPLite可能没有状态,因此可能为空
- ESTABLISHED: TCP三次握手成功,已经建立正常的连接,可以随时进行数据传输
- SYN_SENT: 主动打开,主动握手的一方发送第一次握手后的状态
- SYN_RECV: 被动握手的一方接收到第一次握手消息后的状态
- FIN_WAIT1: 主动关闭的一方,发送第一次挥手消息(FIN)后的状态
- FIN_WAIT2: 主动关闭的一方,接收到第二次挥手后的状态
- TIME_WAIT: 主动关闭的一方,发送完第四次挥手后的状态,需要等待2MSL时间后才能进入CLOSED状态(Centos上是60s,并且不能通过配置参数修改),TIME_WAIT只发生在主动关闭的一方。
- CLOSE: 套接字未被使用
- CLOSE_WAIT: 被动关闭的一方,发送第二次挥手的状态
- LAST_ACK: 被动关闭的一方,发送第三次挥手后的状态
- LISTEN: 套接字正在监听的状态,除非指定 -l 或者 -a 参数才能显示
- CLOSING: 两个套接字都已经关闭了,但是仍然还有数据没有发送完的状态
- UNKNOWN: 未知的套接字状态
- User: 套接字所有者的用户名或者UID
- PID/Program name: 进程id和进程名字,如果某个套接字不属于自己,则需要超级用户权限才能查看那个套接字的进程id和进程名字
- Active UNIX domain sockets,称为有源UNIX域套接口(和网络套接字一样,但是只能用于本机通信,性能可以提高一倍)
- Proto: 套接字使用的协议,通常是unix
- RefCnt: 套接字计数,通过此套接字连接的进程
- Flags: 显示的标志为SO_ACCEPTON(显示为ACC)、SO_WAITDATA(W)或SO_NOSPACE(N)
- Type: 套接字的类型
- State: 套接字的状态
- FREE: 未分配套接字
- LISTENING: 套接字正处于监听状态
- CONNECTING: 套接字即将建立连接
- CONNECTED: 套接字已连接
- DISCONNECTING: 套接字已经断开连接了
- (empty): 套接字没有连接到其他套接字
- UNKNOWN: 未知状态,不过这种状态永远都不会发生
- PID/Program name: 套接字的进程id和进程名字
- Path: 连接到套接字的进程路径名
常用参数
- -a或 –all: 显示所有选项
- -i、-I=iface、–interface=iface: 显示所有的网络接口或者指定的网络接口
- -t(tcp): 仅显示tcp相关选项
- -u(udp): 仅显示udp相关选项
- -l: 仅显示监听的服务
- -p或 –program:显示每个套接字所属程序的PID和名称
- -r: 显示路由信息
- -e或 –extend: 显示其他信息。使用此选项两次可获得最大细节
- -s或 –statistics: 显示每个协议的摘要统计信息
- -c或 –continuous: 每隔一个固定时间执行一次netstat命令
- -o或 –timers: 显示与网络计时器相关的信息
常用例子
- 显示所有连接
netstat -a
- 显示所有tcp端口
netstat -at
- 显示所有udp端口
netstat -au
- 显示所有监听状态的端口
netstat -l
- 显示所有监听的tcp端口
netstat -lt
- 显示所有监听的tcp端口并列出进程id,进程名字
netstat -ltp
- 显示所有监听的tcp端口并列出进程id,进程名字,并且不解析主机名称服务名称(会快很多)
netstat -lntp
- 查看监听80端口的TCP服务
netstat -lntp|grep 80
- 显示网络接口列表
netstat -i
- 显示网络接口详细信息
netstat -ie
- 查看路由信息
netstat -r
- 统计所有的tcp套接字数量
netstat -ant|wc -l
- 按状态统计TCP连接数
# 两种写法都一样
netstat -ant|egrep -v 'Active|State'|awk '{print $6}'|sort|uniq -c
netstat -ant|awk 'NR > 2{print $6}'|sort|uniq -c
- 统计远程的TCP连接数,按倒序排序
netstat -tn | awk 'NR > 2 {print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -rnk1
- 统计本机监听的tcp端口的连接数,按倒序排序
netstat -tn|awk 'NR > 2 {print $4}'|awk -F: '{print $NF}'|sort|uniq -c|sort -rnk1