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

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

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

python -m SimpleHTTPServer

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

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

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

15 ответов

Решение

У вас уже есть процесс, связанный с портом по умолчанию (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 и выше, если порт еще не занят.

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

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

    sudo lsof -i:8080

  2. Убей это:

    kill XXXX

Используйте lsof -i:5000. Это даст вам список процессов, использующих порт, если он есть. После того, как список процессов задан, используйте идентификатор в столбце PID для завершения процесса: например, kill 379

Простая однострочная команда, чтобы избавиться от нее, введите команду ниже в терминале,

ps -a

Это перечислит весь процесс, извлечение которого используется Python, и введите команду bellow в терминале,

kill -9 (processID) 

Например убить -9 33178

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

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

Вы можете разрешить серверу повторно использовать адрес с помощью 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()

Вы также можете обслуживать следующий по величине доступный порт, выполняя что-то подобное в 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-скрипт не захватывает порт - другой процесс может захватить порт раньше, чем ваш процесс (условие гонки) - но все же может быть достаточно полезен при использовании утилиты, которая не ' у меня нет собственного подхода.

Я новичок в Python, но после краткого исследования я обнаружил, что это типично для связывания сокетов. Просто так получилось, что сокет все еще используется, и вам, возможно, придется подождать, чтобы его использовать. Или вы можете просто добавить:

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

Это должно сделать порт доступным в более короткие сроки. В моем случае это сделало порт доступным практически сразу.

Дело со мной

Это происходит, когда я отлаживаю или запускаю сервер, а когда закончу, вместо Terminatingпроцесса я Disconnectего.

PyCharm запрашивает эти два параметра, когда мы пытаемся закрыть его, пока сервер все еще работает.

Это приводит к тому, что процесс по-прежнему работает в фоновом режиме на этом конкретном адресе, следовательно, Address already in use ошибка.

Решение

      pkill python

Работает для меня.

Другой случай - множественные процессы

Если у вас есть несколько серверов / приложений, работающих с python (очевидно, на разных портах 😅), то получите PID этого процесса с использованием PORT а также killэто .

      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 , kill / pkill / killall, lsof

Намасте 🙏

На всякий случай вышеприведенные решения не сработали:

  1. Получите порт, который слушает ваш процесс:

    $ ps ax | grep python

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

    $ kill PROCESS_NAME

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

Это типичный вариант использования для любого разработчика.

Лучше, чтобы он функционировал в вашей локальной системе. (Так что лучше сохранить этот скрипт в одном из профилей оболочки, таких как ksh / zsh или профиль bash, в зависимости от предпочтений пользователя)

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

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

      killport port_number

Пример:

      killport 8080

Эта ошибка возвращается из-за попытки перезапустить проект, пока он еще выполняется. Остановите и перезапустите проект.

Добавление к ответу Майкла Шмида Просто возникла проблема, чтобы разрешить повторную привязку использования порта, необходимо ПОДКЛАССИРОВАТЬ сервер сокетов следующим образом:

      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 или того, что вы используете.

Единственное решение, которое помогло мне, — это перезагрузить ноутбук.

Другие вопросы по тегам