socket.error: [Errno 48] Адрес уже используется


224

Я пытаюсь настроить сервер с python из терминала Mac.

Я перехожу к папке с использованием:

python -m SimpleHTTPServer

Но это дает мне ошибку:

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

Ранее я открывал соединение с помощью той же команды для другого веб-сайта в другом месте на моем компьютере.


2
Убейте другой процесс или запустите этот с другим портом:python -m SimpleHTTPServer 8081
Blender

Ответы:


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сигнал; если процесс не отвечает, вам, возможно, придется прибегнуть к более жестким методам, таким как отправка SIGKILL( kill -s KILL <pid>или kill -9 <pid>) сигнала. Смотрите Википедию для более подробной информации .

Либо запустите сервер на другом порту, указав альтернативный порт в командной строке:

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

затем получить доступ к серверу как http://localhost:8910; где 8910может быть любое число от 1024 и выше, если порт еще не занят.


Какой URL я должен иметь в браузере, чтобы увидеть, работает ли он? Я использую другой порт, как вы предложили
irm

14
возможно, потребуется использоватьsudo kill -9 PID
Данпе

Спасибо, @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: также см. статью о сигналах Unix в Википедии.
Мартин Питерс

153

Простое решение :

  1. Найдите процесс, используя порт 8080:

    sudo lsof -i:8080

  2. Убей это:

    kill XXXX


8
Этот ответ будет полезен на примере того, как lsofможет выглядеть вывод, и как найти идентификатор процесса (список «XXXX») в выводе. Для тех, кто видит это без этой информации, это второе поле в выводе под меткой заголовка «PID».
Линд

2
@lindes Вы крэк!
Карлос Родригес

@ CarlosRodríguez: а? Я действительно не знаю, что вы имеете в виду под этим комментарием (я знаю несколько определений «крэка», и те, которые я знаю, похоже, не подходят ...)
lindes

2
@ CarlosRodríguez Я хочу верить, что он нашел ваш ответ абсолютно точно. Я думаю, что ваше наблюдение о необходимости дать примеры выходных данных lsof и о том, как идентифицировать PID, очень важно. Вторым элементом в каждой возвращаемой строке обычно является PID, он всегда находится под столбцом PID вывода
Kudehinbu Oluwaponle

33

использование

 sudo lsof -i:5000

Это даст вам список процессов, использующих порт, если таковые имеются. Как только список процессов задан, используйте идентификатор в столбце PID, чтобы прекратить использование процесса

 kill 379 #use the provided PID

Это прекрасно, особенно те, кто работает над MAC OSX и не использует SO_REUSEPORT вместо SO_REUSEADDR
snr

16

Кстати, чтобы этого не происходило, просто нажмите Ctrl+ Cв терминале, пока SimpleHTTPServer по-прежнему работает нормально. Это «правильно» остановит сервер и освободит порт, поэтому вам не придется снова находить и завершать процесс перед перезапуском сервера.

(Моды: я пытался поставить этот комментарий на лучший ответ, где он принадлежит, но мне не хватает репутации.)


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 ax | grep python

  2. Убить процесс

    $ kill PROCESS_NAME


3

У меня есть Raspberry Pi, и я использую веб-сервер Python (используя Flask). Я попробовал все выше, единственное решение - закрыть терминал (оболочку) и открыть его снова. Или перезапустите Raspberry Pi , потому что ничто не останавливает этот веб-сервер ...


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()
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.