socket.error: [Errno 48] 地址已在使用中

Posted

技术标签:

【中文标题】socket.error: [Errno 48] 地址已在使用中【英文标题】:socket.error: [Errno 48] Address already in use 【发布时间】:2013-10-04 23:25:19 【问题描述】:

我正在尝试从 mac 终端使用 python 设置服务器。

我导航到文件夹位置并使用:

python -m SimpleHTTPServer

但这给了我错误:

socket.error: [Errno 48] Address already in use

我之前使用相同的命令打开了一个连接 用于我机器中不同位置的不同网站。

【问题讨论】:

杀死另一个进程或使用不同的端口运行这个进程:python -m SimpleHTTPServer 8081 【参考方案1】:

您已经有一个绑定到默认端口 (8000) 的进程。如果您之前已经运行过相同的模块,则很可能该进程仍绑定到该端口。先尝试定位其他进程:

$ ps -fA | grep python
  501 81651 12648   0  9:53PM ttys000    0:00.16 python -m SimpleHTTPServer

包含命令参数,因此如果多个python 进程处于活动状态,您可以发现正在运行的SimpleHTTPServer。您可能想测试http://localhost:8000/ 是否仍显示本地文件的目录列表。

第二个数字是进程号;通过发送信号停止服务器:

kill 81651

这会发送一个标准的SIGTERM 信号;如果该过程没有响应,您可能不得不求助于更严格的方法,例如发送SIGKILLkill -s KILL <pid>kill -9 <pid>)信号。见Wikipedia for more details。

或者,通过在命令行上指定备用端口,在不同的端口上运行服务器:

$ python -m SimpleHTTPServer 8910
Serving HTTP on 0.0.0.0 port 8910 ...

然后以http://localhost:8910 访问服务器;其中8910 可以是 1024 及以上的任何数字,前提是该端口尚未被占用。

【讨论】:

我应该在浏览器中使用什么 url 来查看它是否有效?正如你所建议的,我正在另一个端口上运行 可能需要使用sudo kill -9 PID 谢谢,@Danpe,我尝试了“sudo kill PID”,但没有成功,但“sudo kill -9 PID”杀死了进程。任何人都知道 -9 指定什么?甚至 sudo 手册似乎也没有涵盖这个参数sudo.ws/man/sudo.man.html @seokhoonlee:kill 向进程发送信号,它可以决定处理(如正常关闭或轮换日志文件)。这些信号是整数(每个都有名称),默认为 15,表示TERMterminate。使用 -9 发送信号 9,KILL,进程无法捕获并忽略该信号,操作系统将结束进程,无论它喜欢与否。 @seokhoonlee:另见***上的Unix signal article。【参考方案2】:

简单的解决方案:

    使用端口8080查找进程:
sudo lsof -i:8080
    杀死该端口上的进程:
kill $PID

kill -9 $PID  //to forcefully kill the port

PID 来自步骤 1 的输出。

【讨论】:

这个答案将受益于lsof 输出可能是什么样子的示例,以及如何在输出中找到进程 ID(您列出的“XXXX”)。对于任何在没有该信息的情况下看到此内容的人,它是输出中的第二个字段,位于“PID”标题标签下。 @lindes 你是个神器! @CarlosRodríguez:嗯?我真的不知道你的评论是什么意思(我知道“裂缝”的多种定义,而我知道的那些似乎不适合......) @CarlosRodríguez 我想相信他发现你的回答绝对正确。我认为您对需要提供 lsof 输出样本以及如何识别 PID 的观察非常重要。返回的每一行的第二项通常是PID,它总是在输出的PID列下 @mercury -9 是 -KILL 的射手格式 --> 使用 kill 命令可以指定一些信号,而 -KILL 或 -9 是信号之一...【参考方案3】:

使用

 sudo lsof -i:5000

这将为您提供使用该端口的进程列表(如果有)。 给出进程列表后,使用 PID 列上的 id 终止进程使用

 kill 379 #use the provided PID

【讨论】:

太完美了,尤其是那些在 MAC OSX 上工作并且没有使用 SO_REUSEPORT 而不是 SO_REUSEADDR 的人【参考方案4】:

简单的一行命令来摆脱它,在终端输入以下命令,

ps -a

这将列出 Python 正在使用的所有进程,结帐并在终端中键入以下命令,

kill -9 (processID) 

例如杀死 -9 33178

【讨论】:

在 MacOSX 上工作(我不知道这是否相关),但我必须使用“-9”参数才能使其工作。这是唯一提到这一点的答案。【参考方案5】:

顺便说一句,为了防止这种情况发生,只需在 SimpleHTTPServer 仍在正常运行时在终端中按 Ctrl+C 即可。这将“正确”停止服务器并释放端口,因此您不必在重新启动服务器之前再次查找并终止该进程。

(Mods:我确实尝试将此评论放在它所属的最佳答案上,但我没有足够的声誉。)

【讨论】:

这里有有用的信息,我不自觉地按了 Ctrl+Z 并且该过程保持活跃。 Ctrl+C 释放端口,因此无需手动终止它。【参考方案6】:

您可以允许服务器重复使用allow_reuse_address 的地址。

服务器是否允许重用地址。这默认为False,并且可以在子类中设置以更改策略。

import SimpleHTTPServer, SocketServer
PORT = 8000
httpd = SocketServer.TCPServer(("", PORT), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.allow_reuse_address = True
print "Serving at port", PORT
httpd.serve_forever()

【讨论】:

在实例化之前,必须在类而不是对象/实例上设置属性:SocketServer.TCPServer.allow_reuse_address = True(来自***.com/a/15278302/106019)。将 TCPServer 继承到一个新类并在那里设置值可能更干净。【参考方案7】:

您还可以在下一个最高可用端口上提供服务,在 Python 中执行类似的操作:

import SimpleHTTPServer
import SocketServer

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler

port = 8000
while True:
    try:
        httpd = SocketServer.TCPServer(('', port), Handler)
        print 'Serving on port', port
        httpd.serve_forever()
    except SocketServer.socket.error as exc:
        if exc.args[0] != 48:
            raise
        print 'Port', port, 'already in use'
        port += 1
    else:
        break

如果您需要对其他实用程序执行相同的操作,则作为 bash 脚本可能更方便:

#!/usr/bin/env bash

MIN_PORT=$1:-1025
MAX_PORT=$2:-65535

(netstat -atn | awk 'printf "%s\n%s\n", $4, $4' | grep -oE '[0-9]*$'; seq "$MIN_PORT" "$MAX_PORT") | sort -R | head -n 1

将其设置为名称为 get-free-port 的可执行文件,您可以执行以下操作:

someprogram --port=$(get-free-port)

这不如原生 Python 方法可靠,因为 bash 脚本不捕获端口——另一个进程可能在你的进程捕获端口之前(竞争条件)——但在使用实用程序时仍然可能足够有用没有自己的重试方法。

【讨论】:

【参考方案8】:

我是 Python 新手,但经过简短研究后,我发现这是绑定套接字的典型情况。碰巧套接字仍在使用中,您可能必须等待才能使用它。或者,您可以添加:

tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

这应该会使端口在更短的时间内可用。就我而言,它几乎立即使端口可用。

【讨论】:

【参考方案9】:

以防万一上述解决方案不起作用:

    获取你的进程正在监听的端口:

    $ ps 斧头 | grep 蟒蛇

    杀死进程

    $ kill PROCESS_NAME

【讨论】:

【参考方案10】:

我有一个树莓派,我正在使用 python Web 服务器(使用 Flask)。我已经尝试了以上所有方法,唯一的解决方案是关闭终端(shell)并再次打开它。或者重新启动树莓派,因为没有什么能阻止网络服务器...

【讨论】:

【参考方案11】:

我的案例

当我调试或运行服务器时会发生这种情况,完成后,我不是终止进程,而是断开它。

当我们在服务器仍在运行时尝试关闭 PyCharm 时,PyCharm 会询问这两个选项

这导致进程仍在该特定地址的后台运行,因此出现Address already in use 错误。

解决方案

pkill python

适合我。

另一个案例 - 多个进程

如果您有多个使用 python 运行的服务器/应用程序(显然,在不同的端口?),那么使用PORTkill 它获取该进程的PID

sudo lsof -i :5000 # here 5000 is the port number  

| COMMAND | PID    | USER     | FD | TYPE | DEVICE | SIZE/OFF | NODE | NAME                    |
|---------|--------|----------|----|------|--------|----------|------|-------------------------|
| python  | 185339 | username | 7u | IPv4 | 598745 | 0t0      | TCP  | localhost:5000 (LISTEN) |
| python  | 185348 | username | 7u | IPv4 | 598745 | 0t0      | TCP  | localhost:5000 (LISTEN) |
| python  | 185350 | username | 8u | IPv4 | 598745 | 0t0      | TCP  | localhost:5000 (LISTEN) |


kill -9 185339 # here 185339 is the PID from above output; keep the -9 as it is

检查@Andrew 的回答,以防止将来发生这种情况。

参考:kill command、kill/pkill/killall、lsof

合十礼?

【讨论】:

【参考方案12】:

这对于任何开发人员来说都是常见的用例。

最好将它作为本地系统中的功能。 (所以最好根据用户偏好将此脚本保存在 ksh/zsh 或 bash 配置文件等 shell 配置文件中)

function killport 
   kill -9 `lsof -i tcp:"$1" | grep LISTEN | awk 'print $2'`

用法:

killport port_number

例子:

killport 8080

【讨论】:

【参考方案13】:

添加来自Michael Schmid的答案 刚刚遇到问题,要允许重新绑定端口使用需要像这样对套接字服务器进行SUBCLASS:

from socketserver import TCPServer, BaseRequestHandler
from typing import Tuple, Callable
class MySockServer(TCPServer):
    def __init__(self, server_address: Tuple[str, int], RequestHandlerClass: Callable[..., BaseRequestHandler]):
        self.allow_reuse_address = True
        super().__init__(server_address, RequestHandlerClass)

因为在实例化之后,更改该标志没有意义。 然后使用它代替 TCPServer 或您正在使用的任何东西。

【讨论】:

【参考方案14】:

返回此错误是因为在项目仍在运行时尝试重新运行该项目。停止并重新启动项目。

【讨论】:

以上是关于socket.error: [Errno 48] 地址已在使用中的主要内容,如果未能解决你的问题,请参考以下文章

selenium:socket.error: [Errno 61] 连接被拒绝

Python 处理 socket.error:[Errno 104] 连接由对等方重置

python绑定socket.error:[Errno 13]权限被拒绝

socket.error:[errno 99] 无法在 python 中分配请求的地址和命名空间

Python rpyc“socket.error:[Errno 113]没有到主机的路由”

Python socket.error:[Errno 111] 连接被拒绝