socket.error: [Errno 48] Dirección ya en uso

224

Estoy tratando de configurar un servidor con Python desde la terminal de Mac.

Navego a la ubicación de carpeta y uso:

python -m SimpleHTTPServer

Pero esto me da un error:

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

Anteriormente había abierto una conexión usando el mismo comando para un sitio web diferente en una ubicación diferente en mi máquina.

irm
fuente
2
Elimine el otro proceso o ejecute este con un puerto diferente:python -m SimpleHTTPServer 8081
Blender

Respuestas:

356

Ya tiene un proceso vinculado al puerto predeterminado (8000). Si ya ejecutó el mismo módulo anteriormente, lo más probable es que el proceso aún esté vinculado al puerto. Intente localizar el otro proceso primero:

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

Se incluyen los argumentos del comando, por lo que puede detectar el que se está ejecutando SimpleHTTPServersi hay más de un pythonproceso activo. Es posible que desee probar si http://localhost:8000/todavía muestra una lista de directorios para archivos locales.

El segundo número es el número de proceso; Detenga el servidor enviándole una señal:

kill 81651

Esto envía una SIGTERMseñal estándar ; Si el proceso no responde, puede que tenga que recurrir a métodos más duros como enviar una señal SIGKILL( kill -s KILL <pid>o kill -9 <pid>) en su lugar. Ver Wikipedia para más detalles .

Alternativamente, ejecute el servidor en un puerto diferente , especificando el puerto alternativo en la línea de comando:

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

luego acceda al servidor como http://localhost:8910; donde 8910puede haber cualquier número desde 1024 en adelante, siempre que el puerto no esté tomado.

Martijn Pieters
fuente
¿Qué url debo tener en el navegador para ver si funciona? Me estoy ejecutando en un puerto diferente como sugeriste
irm
14
podría necesitar usarsudo kill -9 PID
Danpe
Gracias, @Danpe, intenté "sudo kill PID" que no funcionó pero "sudo kill -9 PID" mató el proceso. Alguien sabe lo que especifica -9? Incluso el manual de sudo no parece cubrir este parámetro sudo.ws/man/sudo.man.html
seokhoonlee
3
@seokhoonlee: killenvía una señal al proceso, que puede decidir manejar (como cerrar con gracia o rotar un archivo de registro). Estas señales son enteros (cada uno con un nombre), el valor predeterminado es 15, lo que significa TERMo termina . El uso de -9 envía la señal 9, KILLque un proceso no puede detectar e ignorar, y el sistema operativo finalizará el proceso si le gusta o no.
Martijn Pieters
@seokhoonlee: también vea el artículo sobre señales de Unix en Wikipedia.
Martijn Pieters
153

Solución simple:

  1. Encuentre el proceso usando el puerto 8080:

    sudo lsof -i:8080

  2. Mátalo:

    kill XXXX

Caracol
fuente
8
Esta respuesta se beneficiaría de un ejemplo de cómo lsofse vería el resultado y cómo encontrar el ID del proceso (el "XXXX" que usted enumera) dentro del resultado. Para cualquiera que vea esto sin esa información, es el segundo campo en la salida, bajo una etiqueta de encabezado de "PID".
lindes
2
@lindes Eres un crack!
Carlos Rodríguez
@ CarlosRodríguez: ¿eh? Realmente no sé a qué te refieres con ese comentario (conozco varias definiciones de "crack", y las que sé que no parecen encajar ...)
lindes
2
@ CarlosRodríguez Quiero creer que encontró su respuesta absolutamente en el punto. Creo que su observación sobre la necesidad de dar muestras de la salida de lsof y cómo identificar PID es muy importante. El segundo elemento en cada fila devuelta suele ser el PID, siempre está debajo de la columna PID de la salida
Kudehinbu Oluwaponle
33

Utilizar

 sudo lsof -i:5000

Esto le dará una lista de procesos que utilizan el puerto, si corresponde. Una vez que se proporciona la lista de procesos, use la identificación en la columna PID para terminar el uso del proceso.

 kill 379 #use the provided PID
el hombre de los dulces
fuente
Eso es perfecto, especialmente aquellos que trabajan en MAC OSX y no usaron SO_REUSEPORT en lugar de SO_REUSEADDR
snr
16

Por cierto, para evitar que esto suceda en primer lugar, simplemente presione Ctrl+ Cen el terminal mientras SimpleHTTPServer todavía se está ejecutando normalmente. Esto "correctamente" detendrá el servidor y liberará el puerto para que no tenga que encontrar y eliminar el proceso nuevamente antes de reiniciar el servidor.

(Mods: intenté poner este comentario en la mejor respuesta a la que pertenece, pero no tengo suficiente reputación).

Mark Chapel
fuente
12

Comando simple de una línea para deshacerse de él, escriba el siguiente comando en la terminal,

ps -a

Esto enumerará todo el proceso, la comprobación que está siendo utilizada por Python y el comando de tipo siguiente en la terminal,

kill -9 (processID) 

Por ejemplo kill -9 33178

Aditya
fuente
7

También puede servir en el siguiente puerto más alto disponible haciendo algo como esto en 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

Si necesita hacer lo mismo para otras utilidades, puede ser más conveniente como un 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

Configure eso como un ejecutable con el nombre get-free-porty puede hacer algo como esto:

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

Eso no es tan confiable como el enfoque nativo de Python porque el script bash no captura el puerto, otro proceso podría tomar el puerto antes de que lo haga su proceso (condición de carrera), pero aún puede ser lo suficientemente útil cuando se utiliza una utilidad que no No tiene un enfoque de prueba-prueba-otra vez.

Chris Johnson
fuente
6

Soy nuevo en Python, pero después de mi breve investigación descubrí que esto es típico de los zócalos conectados. Sucede que todavía se usa el zócalo y es posible que tenga que esperar para usarlo. O simplemente puede agregar:

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

Esto debería hacer que el puerto esté disponible en un tiempo más corto. En mi caso, hizo que el puerto estuviera disponible casi de inmediato.

VenenoIvee
fuente
4

Por si las soluciones anteriores no funcionaban:

  1. Obtenga el puerto que su proceso está escuchando:

    $ ps hacha | grep python

  2. Mata el proceso

    $ kill PROCESS_NAME

usuario3305074
fuente
3

Tengo un raspberry pi y estoy usando el servidor web Python (usando Flask). He intentado todo lo anterior, la única solución es cerrar el terminal (shell) y abrirlo nuevamente. O reinicie la frambuesa pi , porque nada detiene ese servidor web ...

Thiago Farias
fuente
2

Puede permitir que el servidor reutilice una dirección con allow_reuse_address.

Si el servidor permitirá la reutilización de una dirección. El valor predeterminado es False, y se puede establecer en subclases para cambiar la política.

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
fuente