现代Linux系统更倾向于使用ss命令,因其通过netlink直接与内核通信,性能更高、信息更全、支持精细过滤,尤其在处理大量连接时远优于依赖解析/proc文件的netstat。

在Linux系统中,要查看当前系统开放或正在使用的端口,最常用的两个命令是
和
。它们都能提供端口的监听状态、已建立的连接以及相关的进程信息。虽然
是老牌
工具,但在现代Linux发行版中,
因其更高的效率和更丰富的功能,正逐渐成为首选。
解决方案
要查看Linux中的端口,我们可以利用
或
命令配合不同的参数。
使用 命令:
命令是
的缩写,它能直接从内核获取套接字信息,因此在处理大量连接时,通常比
更快。
-
查看所有监听的TCP和UDP端口(数字格式):
这里
表示TCP, 表示UDP, 表示监听状态, 表示以数字形式显示端口号和IP地址,而不是尝试解析服务名或主机名。这是我个人最常用的组合,能快速概览哪些服务在等待连接。
-
查看所有已建立的TCP连接:
显示所有(监听和非监听)套接字。
-
查看所有连接及其关联的进程信息:
会显示拥有该套接字的进程名和PID。这在排查哪个程序占用了某个端口时非常有用。
使用 命令:
(network statistics)也是一个功能强大的网络工具,但它通过解析
目录下的文件来获取信息,在大连接量下可能会显得有些慢。
-
查看所有监听的TCP和UDP端口(数字格式):
参数含义与
命令类似。
-
查看所有连接及其关联的进程信息:
同样,
参数用于显示进程信息。
-
查看所有TCP连接的详细信息:
这里的
表示所有连接,表示数字显示,表示TCP协议。
通常,我会优先使用
,因为它在性能上的优势是实实在在的。但如果我面对的是一个较老的系统,或者习惯性地敲下了
,它也一样能完成任务。
为什么现代Linux系统更倾向于使用命令来查看网络连接?
现代Linux系统之所以更推荐使用
而非
,核心原因在于它们的底层实现机制差异巨大。
的历史可以追溯到很久以前,它主要通过读取
、
等文本文件来获取网络连接信息。这种方式在连接数量不多时尚可接受,但当系统上有成千上万个连接(比如一个繁忙的Web服务器或数据库服务器)时,解析这些庞大的文本文件会变得非常低效,甚至可能导致命令执行缓慢,占用大量CPU资源。我记得有一次在生产环境排查一个连接泄漏问题,
跑起来简直是煎熬,命令行卡了半天,而
几乎是秒出结果,那一刻真是体会到什么叫“现代工具”的优势。
相比之下,
命令直接利用了Linux内核提供的
套接字机制。
是一种更高效的内核与用户空间通信方式,它允许
直接向内核查询网络统计信息,避免了文件解析的开销。这使得
在以下几个方面表现出显著优势:
-
性能卓越: 对于大量并发连接的系统,的执行速度远超,能够更快地返回结果,极大地提高了故障排查效率。
-
信息更丰富: 能够提供比更详细的TCP连接状态信息,比如TCP窗口大小()、缓冲区大小(、)、TCP状态机定时器信息()、RTT(往返时间)等。这些额外的信息对于深入分析网络性能问题和诊断疑难杂症非常有帮助。
-
功能更强大: 支持更复杂的过滤和查询条件,例如可以根据TCP状态、源/目的地址、端口范围等进行精细化过滤,这让查找特定连接变得更加便捷。
所以,虽然
依然可用,但在追求效率和深度分析的场景下,
无疑是更优的选择。很多Linux发行版甚至已经将
标记为“过时”,推荐用户转向
。
如何使用或命令过滤和查找特定的端口连接?
在实际操作中,我们很少需要查看所有的端口信息,更多时候是想找到特定端口、特定状态或特定程序的连接。
和
都提供了强大的过滤能力。
过滤特定端口:
最直接的方法就是结合
命令。
- 查找监听在80端口的TCP服务:
ss -tuln | grep ':80'
登录后复制
或者使用
:netstat -tuln | grep ':80'
登录后复制
- 查找与SSH(22端口)相关的连接:
ss -ant | grep ':22'
登录后复制
这里
显示所有连接,数字显示,只显示TCP。
过滤特定状态:
命令可以直接通过
关键字进行状态过滤,这比
结合
效率更高。
- 查找所有处于(已建立)状态的TCP连接:
ss -tn state established
登录后复制
- 查找所有处于(监听)状态的TCP连接:
ss -tn state listening
登录后复制
- 查找所有处于状态的连接(这对于诊断高并发服务器上的连接资源耗尽问题很有用):
ss -tn state time-wait
登录后复制
通常需要先列出所有连接,再通过过滤状态,效率稍低:netstat -ant | grep ESTABLISHED
登录后复制
过滤特定协议:
过滤特定程序或PID:
使用
参数可以显示拥有该套接字的进程信息。
- 查找所有由服务打开的连接:
或者查找占用某个特定端口的进程,比如80端口:
ss -apn | grep ':80'
登录后复制
输出会包含进程名和PID,例如
users:(("nginx",pid=1234,fd=5))
登录后复制
。这里有个小技巧,有时候你发现一个端口被占用了,但不知道是哪个程序,或者就能直接告诉你PID和程序名,非常方便。我经常用它来揪出那些“幽灵进程”,比如一个服务崩溃后,它的监听端口可能还被一个僵尸进程或者旧的实例占用着。
通过这些组合和过滤,我们可以非常精确地定位到我们关心的网络连接信息,大大提升了排查问题的效率。
理解和输出中的端口状态和关键信息
掌握了如何使用命令,下一步就是理解它们输出的信息,特别是那些看似神秘的端口状态。这些状态是TCP/IP协议栈内部连接生命周期的体现,理解它们对于网络故障诊断至关重要。
常见的TCP端口状态及其含义:
-
LISTEN (监听): 服务器端程序正在等待客户端连接。端口已打开,并准备接受传入连接。
-
SYN_SENT (同步已发送): 客户端已发送一个SYN(同步)报文请求建立连接,正在等待服务器的SYN/ACK(同步/确认)响应。
-
SYN_RECV (同步已接收): 服务器已收到客户端的SYN报文,并已发送自己的SYN/ACK报文,正在等待客户端的ACK(确认)报文。
-
ESTABLISHED (已建立): TCP连接已经成功建立,双方可以开始进行数据传输。这是最常见的活动连接状态。
-
FIN_WAIT1 (终止等待1): 应用程序已请求关闭连接,并发送了FIN(终止)报文,等待对端的ACK。
-
FIN_WAIT2 (终止等待2): 已收到对端的ACK,现在等待对端发送FIN报文来关闭连接。
-
TIME_WAIT (时间等待): 连接已关闭,但本地套接字仍在等待一段时间,以确保所有迟到的报文段都已在网络中消失。这是TCP连接关闭的最后一个阶段,通常持续2MSL(Maximum Segment Lifetime,最大报文段生存时间)。大量连接可能导致端口资源耗尽,影响新连接的建立。
-
CLOSE_WAIT (关闭等待): 对端已发送FIN报文并关闭了连接,但本地应用程序尚未关闭其套接字。这通常意味着本地应用程序在处理完剩余数据后,需要主动关闭连接。
-
LAST_ACK (最后确认): 本地应用程序已发送FIN报文并收到对端的FIN报文,现在正在等待对端的ACK报文来确认本地的FIN。
-
CLOSING (关闭中): 双方同时发送了FIN报文,但本地在收到对端的FIN之前收到了自己的FIN的ACK。这种情况比较少见。
和输出中的关键字段:
-
Proto (协议): 指示是TCP还是UDP协议。
-
Recv-Q / Send-Q (接收队列/发送队列):
- 对于,通常表示在套接字缓冲区中等待发送或接收的字节数。
- 对于,在状态下,表示接收队列中未被应用程序读取的字节数,表示发送队列中未被远程主机确认的字节数。在状态下,它们可能表示待处理的(未完成三次握手)和已完成三次握手的连接数。
-
Local Address:Port (本地地址:端口): 本地机器的IP地址和端口号。表示监听所有可用的IP地址,表示监听所有IPv6地址。
-
Foreign Address:Port (外部地址:端口): 远程机器的IP地址和端口号。
-
State (状态): 上面解释的TCP连接状态。
-
PID/Program name (进程ID/程序名): 拥有该套接字的进程ID和对应的程序名称。
这些状态看似复杂,但理解了它们,你就能更好地诊断网络问题。比如,如果看到大量
,可能需要调整系统参数(如
net.ipv4.tcp_tw_reuse
登录后复制
或
net.ipv4.tcp_tw_recycle
登录后复制
,尽管后者在某些场景下有争议),或者检查应用层的连接关闭逻辑。我曾经就遇到过一个服务因为
过多,导致无法接受新连接的案例,当时就是通过观察这些状态才定位到问题。而如果发现
持续不减,那往往意味着本地应用程序没有正确关闭连接,可能存在资源泄漏。通过观察这些关键信息,我们能够更深入地理解系统网络行为,从而有效地进行故障排查和性能优化。
以上就是如何在Linux中查看端口 Linux ss与netstat对比的详细内容,更多请关注php中文网其它相关文章!