socket.error: [Errno 48] Indirizzo già in uso


224

Sto cercando di configurare un server con Python dal terminale Mac.

Vado alla posizione della cartella e uso:

python -m SimpleHTTPServer

Ma questo mi dà errore:

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

In precedenza avevo aperto una connessione utilizzando lo stesso comando per un sito Web diverso in una posizione diversa nella mia macchina.


2
Uccidi l'altro processo o eseguilo con una porta diversa:python -m SimpleHTTPServer 8081
Blender,

Risposte:


356

Hai già un processo associato alla porta predefinita (8000). Se hai già eseguito lo stesso modulo in precedenza, è molto probabile che il processo sia ancora associato alla porta. Prova prima a individuare l'altro processo:

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

Gli argomenti del comando sono inclusi, quindi puoi individuare quello in esecuzione SimpleHTTPServerse pythonè attivo più di un processo. Puoi provare se http://localhost:8000/mostra ancora un elenco di directory per i file locali.

Il secondo numero è il numero di processo; arrestare il server inviandogli un segnale:

kill 81651

Questo invia un SIGTERMsegnale standard ; se il processo non risponde potrebbe essere necessario ricorrere a metodi più difficili come l'invio di un segnale SIGKILL( kill -s KILL <pid>o kill -9 <pid>). Vedi Wikipedia per maggiori dettagli .

In alternativa, eseguire il server su una porta diversa , specificando la porta alternativa sulla riga comandi:

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

quindi accedere al server come http://localhost:8910; dove 8910può essere un numero qualsiasi da 1024 in poi, a condizione che la porta non sia già stata presa.


Quale url dovrei avere nel browser per vedere se funziona? Sto correndo su una porta diversa come hai suggerito
irm,

14
potrebbe essere necessario utilizzaresudo kill -9 PID
Danpe l'

Grazie, @Danpe, ho provato "sudo kill PID" che non ha funzionato ma "sudo kill -9 PID" ha interrotto il processo. Qualcuno sa cosa specifica -9? Anche il manuale di sudo non sembra coprire questo parametro sudo.ws/man/sudo.man.html
seokhoonlee

3
@seokhoonlee: killinvia un segnale al processo, che può decidere di gestire (come chiudere con grazia o ruotare un file di registro). Questi segnali sono numeri interi (ciascuno con un nome), il valore predefinito è 15, che significa TERMo termina . L'uso di -9 invia il segnale 9, KILLche un processo non può catturare e ignorare, e il sistema operativo terminerà il processo se lo desidera o meno.
Martijn Pieters

@seokhoonlee: vedi anche l' articolo del segnale Unix su Wikipedia.
Martijn Pieters

153

Soluzione semplice :

  1. Trova il processo utilizzando la porta 8080:

    sudo lsof -i:8080

  2. Uccidilo:

    kill XXXX


8
Questa risposta trarrebbe beneficio da un esempio di come lsofpotrebbe apparire l' output e come trovare l'ID di processo (il "XXXX" che elenchi) all'interno dell'output. Per chiunque lo veda senza tali informazioni, è il secondo campo nell'output, sotto un'etichetta di intestazione di "PID".
termina il

2
@lindes Sei una crepa!
Carlos Rodríguez,

@ CarlosRodríguez: eh? Sinceramente non so cosa intendi con quel commento (conosco più definizioni di "crack", e quelle che conosco non sembrano adattarsi ...)
Lindes

2
@ CarlosRodríguez Voglio credere che abbia trovato la tua risposta assolutamente sul punto. Penso che la tua osservazione sulla necessità di fornire campioni dell'output di lsof e su come identificare il PID sia molto importante. Il secondo elemento in ogni riga restituito è di solito il PID, è sempre sotto la colonna PID dell'output
Kudehinbu Oluwaponle

33

Uso

 sudo lsof -i:5000

Ciò fornirà un elenco di processi che utilizzano la porta, se presente. Una volta fornito l'elenco dei processi, utilizzare l'id sulla colonna PID per terminare l'utilizzo del processo

 kill 379 #use the provided PID

È perfetto, specialmente quelli che lavorano su MAC OSX e non hanno usato SO_REUSEPORT invece di SO_REUSEADDR
snr

16

A proposito, per evitare che ciò accada in primo luogo, è sufficiente premere Ctrl+ Cnel terminale mentre SimpleHTTPServer è ancora in esecuzione normalmente. Ciò "arresterà" correttamente il server e rilascerà la porta in modo da non dover trovare e interrompere nuovamente il processo prima di riavviare il server.

(Mod: ho provato a mettere questo commento sulla migliore risposta a cui appartiene, ma non ho abbastanza reputazione.)


12

Semplice comando a una riga per sbarazzarsene, digitare il comando seguente nel terminale,

ps -a

Questo elencherà tutto il processo, il checkout utilizzato da Python e il comando bellow nel terminale,

kill -9 (processID) 

Ad esempio, uccidi -9 33178


7

Puoi anche servire sulla prossima porta più alta disponibile facendo qualcosa del genere in 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

Se hai bisogno di fare la stessa cosa per altre utility, potrebbe essere più comodo come uno script 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

Impostalo come eseguibile con il nome get-free-porte puoi fare qualcosa del genere:

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

Non è affidabile come l'approccio nativo di Python perché lo script bash non acquisisce la porta - un altro processo potrebbe afferrare la porta prima del tuo processo (condizione di gara) - ma potrebbe essere ancora abbastanza utile quando si utilizza un'utilità che non ' t ha un approccio prova a riprovare.


6

Sono nuovo di Python, ma dopo una breve ricerca ho scoperto che questo è tipico dei socket vincolati. Accade solo che il socket sia ancora in uso e potrebbe essere necessario attendere per usarlo. Oppure puoi semplicemente aggiungere:

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

Ciò dovrebbe rendere la porta disponibile in un tempo più breve. Nel mio caso, ha reso la porta disponibile quasi immediatamente.


4

Nel caso in cui le soluzioni sopra non funzionassero:

  1. Ottieni la porta che il tuo processo sta ascoltando:

    $ ps ax | pitone grep

  2. Uccidi il processo

    $ kill PROCESS_NAME


3

Ho un Raspberry Pi e sto usando Python Web Server (usando Flask). Ho provato tutto sopra, l'unica soluzione è chiudere il terminale (shell) e riaprirlo. O riavvia il raspberry pi , perché nulla ferma quel server web ...


2

È possibile consentire al server di riutilizzare un indirizzo con allow_reuse_address.

Se il server consentirà il riutilizzo di un indirizzo. L'impostazione predefinita è Falsee può essere impostata in sottoclassi per modificare la politica.

import SimpleHTTPServer, SocketServer
PORT = 8000
httpd = SocketServer.TCPServer(("", PORT), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.allow_reuse_address = True
print "Serving at port", PORT
httpd.serve_forever()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.