术语表/出问题的时候

监听端口

又称:打开的端口、端口3000被谁占用

简要回答

监听端口是某个进程在等待传入连接的网络端口,比如在端口3000上运行的Web服务器。同一时间只能有一个进程在某个端口和地址上监听,所以你会看到“address already in use”(地址已被占用)这样的错误。

开发服务器、数据库和一些App会打开监听端口。当你启动服务器却因为端口被占用而失败时,说明另一个进程还在那里监听,常常是同一个服务器之前启动的副本。

活动监视器可以显示某个进程打开的文件和端口,但要找出哪个进程占用了某个端口,最快的方法是在“终端”中使用lsof命令。

如何找出是什么占用了端口

在“终端”中运行lsof -nP -iTCP:3000 -sTCP:LISTEN,把3000换成你的端口号。输出会显示命令名称及其PID。

要列出所有监听中的TCP端口,运行lsof -nP -iTCP -sTCP:LISTEN。在前面加上sudo,就会包括其他用户拥有的进程。

如何释放端口

如果这个进程是你自己启动的服务器,先用正常方式停止它,比如在运行它的终端窗口里按Control-C。否则,用lsof查到的PID运行kill <PID>。只有它不退出时,才使用kill -9 <PID>。

停止进程前先核对进程名称。有些端口属于macOS服务,比如“隔空播放接收器”,在较新的macOS版本上它会监听端口5000和7000。

如何在活动监视器中查看端口

连按一个进程,打开“打开的文件和端口”标签页。它会列出该进程打开的文件和网络连接。

如何看懂lsof的输出

每一行是一个打开的套接字。一个服务器通常显示两行,一行是IPv4,一行是IPv6,PID相同。

  • COMMAND是进程名称,默认截断为9个字符。加上+c 0可以看到完整名称:lsof +c 0 -nP -iTCP -sTCP:LISTEN。
  • PID是你传给kill或ps的进程ID。
  • USER是运行它的账户。root拥有的进程通常属于macOS或某个已安装的服务。
  • NAME显示地址和端口。*:3000表示服务器在所有网络接口上接受连接。127.0.0.1:3000或[::1]:3000表示只有这台Mac能连接。

如何查看开发服务器属于哪个项目

进程名称往往只是node、python或ruby,看不出运行的是哪个项目。有两个命令可以回答这个问题。

  1. 用lsof -nP -iTCP:3000 -sTCP:LISTEN获取PID。
  2. 运行ps -o pid,ppid,command -p <PID>,查看启动它的完整命令。
  3. 运行lsof -a -p <PID> -d cwd,查看它运行所在的文件夹,通常就是项目文件夹。
  4. 如果PPID指向一个shell,说明服务器是从终端窗口启动的。如果那个窗口还开着,就在那里按Control-C停止它。

为什么看起来什么都没运行,端口却被占用了

如果端口属于“隔空播放接收器”,就让你的服务器改用其他端口,或者在“系统设置”>“通用”的“隔空投送与接力”部分关闭“隔空播放接收器”。

  • 之前会话中的服务器,还在某个你忘了的终端标签页或窗口里运行。
  • 服务器是在后台启动的,或者是由编辑器或其他工具启动的,没有可见的窗口。
  • 服务器崩溃了,但它启动的子进程仍然占着端口。
  • 某个macOS服务使用了同一个端口,比如“隔空播放接收器”会使用端口5000和7000。

活动监视器中的“端口”列不是网络端口

活动监视器的“CPU”标签页中有一个可选的“端口”列。它统计的是Mach端口,这是macOS在进程之间传递消息的一种机制,和top显示为ports的数字相同。它并不列出网络端口。要查看网络端口,可以使用lsof,或进程信息窗口中的“打开的文件和端口”标签页。

常见问题

如何查看Mac上的端口3000被谁占用?

在“终端”中运行lsof -nP -iTCP:3000 -sTCP:LISTEN。它会显示在该端口上监听的进程名称和PID。

如何在Mac上结束占用某个端口的进程?

用lsof找到它的PID,然后运行kill <PID>。如果它不退出,kill -9 <PID>会立即结束它。

如何列出Mac上所有打开的端口?

运行lsof -nP -iTCP -sTCP:LISTEN列出监听中的TCP端口。加上sudo,就会包括其他用户的进程。

“address already in use”是什么意思?

已经有另一个进程在那个端口和地址上监听。用lsof -nP -iTCP:<port> -sTCP:LISTEN找到它,然后停止它,或者换一个端口。

端口明明被占用,为什么lsof什么都不显示?

这个进程可能属于其他用户或root。在同一个命令前面加上sudo,就会包括所有进程。

结束占用端口5000或7000的进程安全吗?

不先核对名称就不安全。在较新的macOS版本上,这两个端口常被“隔空播放接收器”使用,你可以改为在“系统设置”中关闭它。

相关条目

分步指南:Docker占用内存过多。

想找比活动监视器更好的工具?请看Mac上最好用的活动监视器替代品,或者浏览术语表中的所有条目。