开发者

Mac 上端口已被占用

一个 TCP 端口和地址只能由一个进程监听。第二个服务器会因“address already in use”而中止。

适用于:所有当前 macOS 版本。核查日期:2026年10月29日

症状

  • 开发服务器因“EADDRINUSE”或“address already in use”而中止。
  • Docker 无法发布端口,提示“port is already allocated”。
  • 崩溃或重启编辑器之前,这个端口还是空闲的。

可能的原因

  • 服务器的旧实例。之前运行的服务器仍在后台运行。
  • 其他 App。另一个 App 占用了同一端口。在 macOS 12 及更高版本上,“隔空播放接收器”使用端口 5000 和 7000。
  • 容器。正在运行的容器在 Mac 上发布了同一端口。

如何检查

  1. 找出监听该端口的进程。将 3000 换成实际端口。

    lsof -nP -iTCP:3000 -sTCP:LISTEN

    输出 COMMAND 和 PID 列显示是哪个进程。

  2. 要查看其他用户的进程,用 sudo 运行同一命令。

    sudo lsof -nP -iTCP:3000 -sTCP:LISTEN

    需要管理员密码。

  3. 显示该进程的更多信息。

    ps -p 12345 -o pid,command
  4. 查找发布了该端口的容器。

    docker ps

如何修复

  1. 如果是你自己的进程,在它所在的“终端”窗口中按 Control-C 停止它。

  2. 否则,向它发送终止信号。使用它的 PID。

    kill 12345
  3. 如果它没有停止,使用 kill -9。进程将无法保存数据。

  4. 如果该进程属于 macOS,不要停止它,为你的服务器换一个端口。

  5. 如果端口是 5000 或 7000,参阅Mac 上端口 5000 或 7000 被占用:隔空播放接收器。

使用 Kilobat

  1. 列出某个进程打开的套接字。

    kilobat destinations --pid 12345
  2. 按 PID 退出进程。只有在它不停止时才加上 --force。

    kilobat quit 12345

常见问题

为什么 lsof 什么也没显示,端口却被占用?

lsof 只显示你有权查看的进程。用 sudo 运行即可看到所有进程。

-n 和 -P 有什么作用?

它们让 lsof 不把地址转换为主机名、不把端口转换为服务名。输出更快,并显示数字。

参考资料

参考资料核查于 2026年10月29日。man 手册页为 macOS 自带版本;在“终端”中用 man <name> 打开。