socket.error: [Errno 48] Adres jest już w użyciu

224

Próbuję skonfigurować serwer z pythonem z terminala Mac.

Przechodzę do lokalizacji folderu i użyj:

python -m SimpleHTTPServer

Ale to daje mi błąd:

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

Wcześniej otworzyłem połączenie za pomocą tego samego polecenia dla innej witryny w innym miejscu na moim komputerze.

irm
źródło
2
Zabij drugi proces lub uruchom ten z innym portem:python -m SimpleHTTPServer 8081
Blender

Odpowiedzi:

356

Proces jest już powiązany z domyślnym portem (8000). Jeśli już wcześniej korzystałeś z tego samego modułu, najprawdopodobniej proces nadal jest powiązany z portem. Najpierw spróbuj zlokalizować inny proces:

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

Argumenty poleceń są uwzględnione, dzięki czemu można wykryć działający, SimpleHTTPServerjeśli pythonaktywny jest więcej niż jeden proces. Możesz sprawdzić, czy http://localhost:8000/nadal wyświetla listę katalogów dla plików lokalnych.

Druga liczba to numer procesu; zatrzymaj serwer, wysyłając mu sygnał:

kill 81651

To wysyła standardowy SIGTERMsygnał; jeśli proces nie odpowiada, może być konieczne zastosowanie trudniejszych metod, takich jak wysyłanie sygnału SIGKILL( kill -s KILL <pid>lub kill -9 <pid>). Zobacz szczegóły w Wikipedii .

Alternatywnie uruchom serwer na innym porcie, określając alternatywny port w wierszu poleceń:

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

następnie uzyskaj dostęp do serwera jako http://localhost:8910; gdzie 8910może być dowolna liczba od 1024 i więcej, pod warunkiem, że port nie jest już zajęty.

Martijn Pieters
źródło
Jaki adres URL powinienem mieć w przeglądarce, aby sprawdzić, czy działa?
Korzystam
14
być może trzeba będzie użyćsudo kill -9 PID
Danpe
Dzięki, @Danpe, próbowałem „sudo kill PID”, które nie działało, ale „sudo kill -9 PID” zabiło proces. Czy ktoś wie, co określa -9? Wydaje się, że nawet podręcznik sudo nie obejmuje tego parametru sudo.ws/man/sudo.man.html
seokhoonlee
3
@seokhoonlee: killwysyła sygnał do procesu, który może zdecydować się obsłużyć (np. zamknąć z wdziękiem lub obrócić plik dziennika). Sygnały te są liczbami całkowitymi (każdy z nazwą), domyślnie 15, co oznacza TERMlub kończy . Użycie -9 powoduje wysłanie sygnału 9, KILLktórego proces nie może złapać i zignorować, a system operacyjny zakończy proces, czy chce, czy nie.
Martijn Pieters
@seokhoonlee: również zobaczyć sygnału Unix artykuł na Wikipedii.
Martijn Pieters
153

Proste rozwiązanie :

  1. Znajdź proces za pomocą portu 8080:

    sudo lsof -i:8080

  2. Zabij to:

    kill XXXX

Ślimak
źródło
8
Ta odpowiedź byłaby korzystna z przykładu tego, jak lsofmogłoby wyglądać wyjście i jak znaleźć identyfikator procesu („XXXX”, który wymieniasz) w danych wyjściowych. Dla każdego, kto widzi to bez tych informacji, jest to drugie pole na wyjściu, pod etykietą nagłówka „PID”.
lipes
2
@lindes You are a crack!
Carlos Rodríguez
@ CarlosRodríguez: huh? Naprawdę nie wiem, co masz na myśli przez ten komentarz (znam wiele definicji „crack” i te, o których wiem, że nie pasują ...)
lindes
2
@ CarlosRodríguez Chcę wierzyć, że znalazł odpowiedź absolutnie na miejscu. Uważam, że wasze spostrzeżenie na temat potrzeby podania próbek wyjściowych lsof i sposobu identyfikacji PID jest bardzo ważne. Drugi element w każdym zwracanym wierszu to zazwyczaj PID, zawsze znajduje się pod kolumną PID wyjścia
Kudehinbu Oluwaponle
32

Posługiwać się

 sudo lsof -i:5000

To da ci listę procesów korzystających z portu, jeśli taki istnieje. Po podaniu listy procesów użyj identyfikatora w kolumnie PID, aby zakończyć użycie procesu

 kill 379 #use the provided PID
cukierkowy facet
źródło
To idealne rozwiązanie, szczególnie ci, którzy pracują na MAC OSX i nie używali SO_REUSEPORT zamiast SO_REUSEADDR
snr
16

Nawiasem mówiąc, aby temu zapobiec, po prostu naciśnij Ctrl+ Cw terminalu, gdy SimpleHTTPServer nadal działa normalnie. Spowoduje to „prawidłowe” zatrzymanie serwera i zwolnienie portu, dzięki czemu nie będziesz musiał ponownie znajdować i zabijać procesu przed ponownym uruchomieniem serwera.

(Mody: Próbowałem umieścić ten komentarz na najlepszej odpowiedzi tam, gdzie należy, ale nie mam wystarczającej reputacji.)

Mark Chapel
źródło
12

Proste polecenie w jednym wierszu, aby się go pozbyć, wpisz poniżej polecenie w terminalu,

ps -a

Spowoduje to wyświetlenie całego procesu, pobranie, które jest używane przez Python i wpisz poniżej polecenie w terminalu,

kill -9 (processID) 

Na przykład zabij -9 33178

Aditya
źródło
7

Możesz także obsługiwać najwyższy dostępny port, robiąc coś takiego w Pythonie:

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

Jeśli musisz zrobić to samo dla innych narzędzi, może to być wygodniejsze jako skrypt 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

Ustaw to jako plik wykonywalny z nazwą get-free-porti możesz zrobić coś takiego:

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

Nie jest to tak niezawodne jak natywne podejście do Pythona, ponieważ skrypt bash nie przechwytuje portu - inny proces może pobrać port, zanim Twój proces to zrobi (warunek wyścigu) - ale nadal może być wystarczająco użyteczny, gdy używasz narzędzia, które nie „ mieć własne podejście typu „spróbuj ponownie”.

Chris Johnson
źródło
6

Jestem nowy w Pythonie, ale po moich krótkich badaniach dowiedziałem się, że jest to typowe dla oprawiania gniazd. Zdarza się, że gniazdo jest nadal używane i być może będziesz musiał poczekać, aby z niego skorzystać. Lub możesz po prostu dodać:

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

To powinno udostępnić port w krótszym czasie. W moim przypadku port był dostępny niemal natychmiast.

PoisonIvee
źródło
4

Na wypadek gdyby powyższe rozwiązania nie działały:

  1. Uzyskaj port, którego nasłuchuje proces:

    $ ps ax | pyton grep

  2. Zabij proces

    $ kill PROCESS_NAME

użytkownik3305074
źródło
3

Mam Raspberry Pi i używam serwera WWW Python (za pomocą Flask). Próbowałem już wszystkiego powyżej, jedynym rozwiązaniem jest zamknięcie terminala (powłoki) i otwarcie go ponownie. Lub zrestartuj Raspberry Pi , ponieważ nic nie powstrzyma tego serwera ...

Thiago Farias
źródło
2

Możesz zezwolić serwerowi na ponowne użycie adresu allow_reuse_address.

Czy serwer pozwoli na ponowne użycie adresu. Domyślnie jest to Falsei można je ustawić w podklasach, aby zmienić zasady.

import SimpleHTTPServer, SocketServer
PORT = 8000
httpd = SocketServer.TCPServer(("", PORT), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.allow_reuse_address = True
print "Serving at port", PORT
httpd.serve_forever()
Michael Schmid
źródło