Linux 系统中如何查看端口占用
在 Linux 系统管理和日常故障排除中,了解哪些进程正在使用特定的网络端口是一项非常基础且重要的技能。当您尝试启动一个新的网络服务(如 Web 服务器、数据库或 SSH 服务器)时,如果遇到“Address already in use”(地址已被占用)的错误,或者需要排查某个服务无法访问的原因时,查看端口占用情况就显得尤为关键。
本文将详细介绍 Linux 系统中常用的几种方法来查看端口占用,包括经典的 netstat 命令、更现代的 ss 命令,以及功能强大的 lsof 命令,并解释如何解读它们的输出信息以及如何查找对应的进程。
理解端口(Port)
在深入查看之前,先简单回顾一下端口的概念。在网络通信中,IP 地址用于标识一台主机,而端口号则用于标识主机上的一个特定的应用程序或服务。端口号是一个16位的数字,范围从0到65535。其中:
- 知名端口 (Well-known ports): 0 到 1023,通常由系统保留,用于标准服务,如 HTTP (80)、HTTPS (443)、SSH (22)、FTP (21) 等。启动这些端口上的服务通常需要 root 权限。
- 注册端口 (Registered ports): 1024 到 49151,可以注册给应用程序使用。
- 动态/私有端口 (Dynamic/Private ports): 49152 到 65535,也称为临时端口 (Ephemeral ports),客户端程序通常使用这些范围内的随机端口与服务器通信。
主要工具
Linux 系统提供了多种命令行工具来查看端口使用情况。最常用的有:
netstat(network statistics)ss(socket statistics)lsof(list open files)
接下来,我们将逐一介绍这些工具的使用方法。
1. 使用 netstat 命令
netstat 是一个历史悠久且功能丰富的网络工具,用于显示网络连接、路由表、接口统计信息等。查看端口占用是其常见用途之一。
查看端口占用的常用选项组合是 -tulnap:
-t: 显示 TCP 协议的连接。-u: 显示 UDP 协议的连接。-l: 仅显示处于监听 (Listening) 状态的套接字。监听状态意味着有服务正在等待传入的连接。-n: 以数字形式显示地址和端口号,而不是尝试解析主机名、服务名等,这样可以加快显示速度。-a: 显示所有连接和监听套接字(包括处于非监听状态的连接)。-p: 显示使用套接字的进程的 PID (Process ID) 和程序名称。执行此选项通常需要 root 权限,否则可能无法看到所有进程信息。
常用示例:
-
查看所有监听的 TCP 端口:
bash
netstat -tulnp | grep tcp
(注意:| grep tcp是为了过滤-tulnp输出中只包含 TCP 的行,虽然-t已经指定了TCP,但-u会包含 UDP,-l显示监听,-n数字格式,-p显示进程,所以-tulnp组合是常用的查看所有监听套接字的通用方式,再用grep过滤更精确。) -
查看所有监听的 UDP 端口:
bash
netstat -tulnp | grep udp -
查看所有连接和监听的 TCP 和 UDP 套接字,并显示进程信息:
bash
sudo netstat -tulnap
(使用sudo是为了确保-p选项能看到所有进程信息) -
查找特定端口(例如 80 端口)的占用情况:
bash
sudo netstat -tulnap | grep :80
或更精确地查找监听在 80 端口的服务:
bash
sudo netstat -tlunp | grep LISTEN | grep :80
(grep LISTEN过滤出监听状态的行,grep :80过滤出端口号为 80 的行。注意端口号前加:可以避免匹配到 PID 或其他数字中的 80)
解读 netstat 输出:
netstat -tulnap 的输出通常包含以下列:
Proto: 协议类型 (tcp, udp)。Recv-Q: 接收队列中等待被程序读取的字节数。Send-Q: 发送队列中等待被远程主机确认的字节数。Local Address: 本地地址和端口号 (IP地址:端口号)。0.0.0.0表示监听本机所有 IPv4 地址,:::表示监听本机所有 IPv6 地址。Foreign Address: 远程地址和端口号。对于监听状态 (LISTEN) 的套接字,这一列通常是0.0.0.0:*或:::*。State: 套接字的状态 (e.g.,LISTEN,ESTABLISHED,CLOSE_WAIT,TIME_WAIT等)。LISTEN表示端口正在监听传入连接。PID/Program name: 占用该端口的进程 ID 和程序名称。
netstat 的局限性:
在非常繁忙的服务器上,netstat 的执行速度可能会比较慢,因为它需要遍历 /proc/net 目录下的文件来收集信息。这是 ss 命令出现的一个原因。
2. 使用 ss 命令
ss 是一个新的、更快的工具,用于查看套接字统计信息。它直接从内核空间获取信息,通常比 netstat 更高效,尤其是在处理大量连接时。ss 旨在取代 netstat 的大部分功能。
ss 命令的选项与 netstat 非常相似,但用法和输出格式略有不同。常用的选项组合是 -tulnap (与 netstat 类似):
-t: 显示 TCP 协议的套接字。-u: 显示 UDP 协议的套接字。-l: 仅显示监听 (Listening) 状态的套接字。-n: 以数字形式显示地址和端口号。-a: 显示所有套接字。-p: 显示使用套接字的进程。同样,通常需要 root 权限。
常用示例:
-
查看所有监听的 TCP 端口:
bash
ss -tulnp | grep tcp -
查看所有监听的 UDP 端口:
bash
ss -tulnp | grep udp -
查看所有连接和监听的 TCP 和 UDP 套接字,并显示进程信息:
bash
sudo ss -tulnap -
查找特定端口(例如 80 端口)的占用情况:
bash
sudo ss -tulnap | grep :80
或查找监听在 80 端口的服务:
bash
sudo ss -tlunp | grep LISTEN | grep :80
解读 ss 输出:
ss 的输出通常包含以下列:
Netid: 网络协议类型 (tcp, udp, u_str, u_dgr)。State: 套接字状态 (LISTEN, ESTAB, etc.)。Recv-Q: 接收队列。Send-Q: 发送队列。Local Address:Port: 本地地址和端口号。Peer Address:Port: 远程地址和端口号。users:(("program_name",pid=PID,fd=FD)): 占用该套接字的进程信息,包括程序名、PID 和文件描述符 (File Descriptor)。这是-p选项提供的详细信息。
ss 的输出通常更加紧凑,并且 -p 选项提供的进程信息格式更清晰。
3. 使用 lsof 命令
lsof (list open files) 是一个非常强大的系统诊断工具,它能列出当前系统打开的所有文件。在 Linux 中,网络套接字也被视为一种特殊类型的文件,因此 lsof 也可以用来查看端口占用。
使用 lsof 查看网络连接的常用选项是 -i。lsof -i 可以显示所有网络连接和监听套接字。
常用示例:
-
查看所有网络连接和监听套接字:
bash
sudo lsof -i
(通常需要sudo来查看所有用户打开的文件) -
查找特定端口(例如 80 端口)的占用情况:
bash
sudo lsof -i :80 -
查找使用特定协议和端口的服务(例如 TCP 协议的 80 端口):
bash
sudo lsof -i tcp:80 -
查找使用特定协议的所有连接(例如所有 TCP 连接):
bash
sudo lsof -i tcp
解读 lsof -i 输出:
lsof -i 的输出包含多列,用于描述打开网络文件的进程和文件本身:
COMMAND: 进程的命令名称。PID: 进程 ID。USER: 进程所有者用户名。FD: 文件描述符。对于网络套接字,通常显示协议类型 (e.g.,4u表示 IPv4 UDP,6t表示 IPv6 TCP) 后面跟着状态 (e.g.,LISTEN,ESTABLISHED)。TYPE: 文件类型。IPv4或IPv6表示网络套接字。DEVICE: 设备号。SIZE/OFF: 文件大小或偏移量。对于网络套接字通常为 0。NODE: 节点的 inode 号。NAME: 网络连接的本地和远程地址信息。格式通常为IP地址:本地端口 -> 远程IP地址:远程端口。对于监听状态,远程地址部分会是*(LISTEN)。
lsof 的优点在于它能非常详细地显示与端口相关的进程信息,包括是哪个用户运行的哪个命令,以及对应的文件描述符。它在排查复杂问题时非常有用。
查找 PID 对应的进程详情
一旦通过 netstat、ss 或 lsof 找到了占用端口的进程 PID,您可以使用 ps 命令来获取该进程的更多详细信息,例如完整的命令行参数。
例如,如果您发现 PID 是 12345 的进程占用了端口:
bash
ps aux | grep 12345
或者更精确地只查找 PID 为 12345 的进程信息:
bash
ps -p 12345 -o cmd
这会直接显示启动该进程时使用的完整命令行,这有助于确定具体是哪个程序或服务占用了端口。
常见端口状态解释 (netstat/ss 的 State 列)
了解端口状态有助于判断连接情况:
LISTEN: 端口正在监听,等待远程连接。这是服务器端进程的常见状态。ESTABLISHED: 连接已经建立,数据正在传输。SYN_SENT: 客户端发送了 SYN 请求,等待服务器回应。SYN_RECV: 服务器收到 SYN 请求并发送了 SYN/ACK 回应,等待客户端的 ACK。FIN_WAIT1: 主动关闭连接的客户端或服务器发送了 FIN 请求,等待对方的 ACK。FIN_WAIT2: 主动关闭连接的一方收到了对方的 ACK,正在等待对方发送 FIN 请求。TIME_WAIT: 主动关闭连接的一方在收到对方 FIN 后进入的状态,等待一段时间确保所有分组都到达,然后关闭连接。CLOSE: 套接字已关闭。CLOSE_WAIT: 被动关闭连接的一方收到 FIN 请求,等待应用程序关闭套接字。LAST_ACK: 被动关闭连接的一方发送 FIN 请求,等待最后一个 ACK。
当您查找端口占用时,通常最关心的是处于 LISTEN 状态的连接,这表示有服务正在使用该端口提供服务。
总结
在 Linux 系统中,netstat、ss 和 lsof 是查看端口占用的主要工具。
netstat是经典的工具,功能全面,但在繁忙系统上可能较慢。ss是更现代、更高效的替代品,推荐优先使用。lsof功能强大,不仅限于查看端口,还能详细显示进程与文件描述符的关系,对于深入排查问题非常有用。
通常,您可以使用 ss -tulnap 或 sudo netstat -tulnap 快速查看系统所有监听的端口及其对应的进程。当需要查找特定端口时,结合 grep :端口号 进行过滤即可。一旦找到进程 ID (PID),可以使用 ps -p PID -o cmd 来获取进程的完整命令行信息,从而确定具体是哪个程序占用了该端口。
熟练掌握这些命令对于 Linux 系统的维护和网络故障诊断至关重要。