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


224

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

我导航到文件夹位置的一种用法:

python -m SimpleHTTPServer

但这给了我错误:

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

之前,我曾使用同一命令为计算机中不同位置的其他网站打开连接。


2
终止另一个进程或使用其他端口运行该进程:python -m SimpleHTTPServer 8081
Blender

Answers:


356

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

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

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

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

kill 81651

这发送一个标准SIGTERM信号;如果该过程没有响应,则您可能不得不采用更严格的方法,例如发送SIGKILLkill -s KILL <pid>kill -9 <pid>)信号。有关更多详细信息,请参见Wikipedia

可替代地,一个上运行服务器不同端口,通过指定在命令行上的备用端口:

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

然后以方式访问服务器http://localhost:8910; 如果8910尚未使用该端口,则可以是1024或更高版本中的任何数字。


我应该在浏览器中使用哪个网址查看其是否正常工作?我在另一个端口上运行
irm

14
可能需要使用sudo kill -9 PID
Danpe 2015年

谢谢@Danpe,我尝试了“ sudo kill PID”,但没有成功,但是“ sudo kill -9 PID”杀死了该进程。有人知道-9指定什么吗?甚至sudo手册似乎也没有涵盖此参数sudo.ws/man/sudo.man.html
seokhoonlee

3
@seokhoonlee:kill向进程发送信号,它可以决定处理(例如正常关闭或旋转日志文件)。这些信号是整数(每个都有一个名称),默认值为15,表示TERM终止。使用-9发送信号9,KILL进程无法捕获并忽略该信号,无论操作系统是否愿意,操作系统都会终止该进程。
马丁·彼得斯

@seokhoonlee:另请参阅Wikipedia上的Unix信号文章
马丁·彼得斯

153

简单的解决方案:

  1. 使用port查找过程8080

    sudo lsof -i:8080

  2. 杀死它:

    kill XXXX


8
该示例将从lsof输出的外观以及如何在输出中查找进程ID(列出的“ XXXX”)的示例中受益。对于没有此信息的任何人,这是输出中第二个字段,标题标签为“ PID”。
林德斯'18

2
@lindes你真是个裂缝!
卡洛斯·罗德里格斯

@CarlosRodríguez:是吗?我真的不知道您所说的意思(我知道“裂纹”的多个定义,而我知道的似乎不适合……)
lindes

2
@CarlosRodríguez我想相信他绝对是您的回应。我认为您对于需要给出lsof输出样本以及如何识别PID的观察非常重要。返回的每一行中的第二项通常是PID,它始终位于输出的PID列下
Kudehinbu Oluwaponle,

32

 sudo lsof -i:5000

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

 kill 379 #use the provided PID

那是完美的,尤其是那些在MAC OSX上工作并且不使用SO_REUSEPORT而不是SO_REUSEADDR的应用程序
snr

16

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

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


12

简单的一行命令即可删除它,在终端中键入以下命令,

ps -a

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

kill -9 (processID) 

例如杀死-9 33178


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脚本无法捕获端口-另一个进程可以在进程捕获端口之前捕获端口(竞赛条件)-但在使用不支持该功能的实用程序时仍然足够有用没有自己尝试的方法。


6

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

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

这将使端口在较短的时间内可用。就我而言,它几乎可以立即使端口可用。


4

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

  1. 获取您的进程正在监听的端口:

    $ ps斧| grep python

  2. 杀死进程

    $杀死PROCESS_NAME


3

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


2

您可以使用允许服务器重用地址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()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.