socket.error: [Errno 48] Adresse déjà utilisée

224

J'essaie de configurer un serveur avec python à partir du terminal mac.

Je navigue vers l'emplacement du dossier et j'utilise:

python -m SimpleHTTPServer

Mais cela me donne une erreur:

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

J'avais précédemment ouvert une connexion en utilisant la même commande pour un site Web différent dans un emplacement différent sur ma machine.

irm
la source
2
Tuez l'autre processus ou exécutez celui-ci avec un port différent:python -m SimpleHTTPServer 8081
Blender

Réponses:

356

Vous avez déjà un processus lié au port par défaut (8000). Si vous avez déjà exécuté le même module auparavant, il est très probable que le processus soit toujours lié au port. Essayez d'abord de localiser l'autre processus:

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

Les arguments de commande sont inclus, vous pouvez donc repérer celui en cours d'exécution SimpleHTTPServersi plusieurs pythonprocessus sont actifs. Vous voudrez peut-être tester si http://localhost:8000/affiche toujours une liste de répertoires pour les fichiers locaux.

Le deuxième nombre est le numéro de processus; arrêtez le serveur en lui envoyant un signal:

kill 81651

Cela envoie un SIGTERMsignal standard ; si le processus ne répond pas, vous devrez peut-être recourir à des méthodes plus sévères comme l'envoi d'un signal SIGKILL( kill -s KILL <pid>ou kill -9 <pid>) à la place. Voir Wikipedia pour plus de détails .

Vous pouvez également exécuter le serveur sur un port différent , en spécifiant le port alternatif sur la ligne de commande:

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

puis accédez au serveur en tant que http://localhost:8910; où 8910peut être n'importe quel nombre de 1024 et plus, à condition que le port ne soit pas déjà pris.

Martijn Pieters
la source
Quelle URL dois-je avoir dans le navigateur pour voir si cela fonctionne? Je cours sur un port différent comme vous l'avez suggéré
irm
14
pourrait avoir besoin d'utilisersudo kill -9 PID
Danpe
Merci, @Danpe, j'ai essayé "sudo kill PID" qui n'a pas fonctionné mais "sudo kill -9 PID" a tué le processus. Quelqu'un sait ce que -9 spécifie? Même le manuel sudo ne semble pas couvrir ce paramètre sudo.ws/man/sudo.man.html
seokhoonlee
3
@seokhoonlee: killenvoie un signal au processus, qu'il peut décider de gérer (comme arrêter gracieusement ou faire pivoter un fichier journal). Ces signaux sont des entiers (chacun avec un nom), la valeur par défaut étant 15, signifiant TERMou se terminant . L'utilisation de -9 envoie le signal 9, KILLqu'un processus ne peut pas attraper et ignorer, et le système d'exploitation mettra fin au processus qu'il le veuille ou non.
Martijn Pieters
@seokhoonlee: consultez également l' article sur le signal Unix sur Wikipedia.
Martijn Pieters
153

Solution simple:

  1. Trouvez le processus en utilisant le port 8080:

    sudo lsof -i:8080

  2. Tue le:

    kill XXXX

Escargot
la source
8
Cette réponse bénéficierait d'un exemple de ce à quoi lsofpourrait ressembler la sortie et comment trouver l'ID de processus (le "XXXX" que vous listez) dans la sortie. Pour tous ceux qui voient cela sans cette information, c'est le deuxième champ dans la sortie, sous une étiquette d'en-tête "PID".
lindes
2
@lindes Vous êtes un crack!
Carlos Rodríguez
@ CarlosRodríguez: hein? Je ne sais vraiment pas ce que vous entendez par ce commentaire (je connais plusieurs définitions de "crack", et celles que je connais ne semblent pas correspondre ...)
lindes
2
@ CarlosRodríguez Je veux croire qu'il a trouvé votre réponse absolument exacte. Je pense que votre observation sur la nécessité de donner des échantillons de la sortie de lsof et comment identifier le PID est très importante. Le deuxième élément de chaque ligne retournée est généralement le PID, il est toujours sous la colonne PID de la sortie
Kudehinbu Oluwaponle
33

Utilisation

 sudo lsof -i:5000

Cela vous donnera une liste des processus utilisant le port, le cas échéant. Une fois la liste des processus fournie, utilisez l'identifiant dans la colonne PID pour terminer l'utilisation du processus

 kill 379 #use the provided PID
candy_man
la source
C'est parfait, surtout ceux qui travaillent sur MAC OSX et qui n'ont pas utilisé SO_REUSEPORT au lieu de SO_REUSEADDR
snr
16

Soit dit en passant, pour éviter que cela ne se produise en premier lieu, appuyez simplement sur Ctrl+C dans le terminal pendant que SimpleHTTPServer fonctionne toujours normalement. Cela arrêtera "correctement" le serveur et libérera le port afin que vous n'ayez pas à rechercher et à tuer le processus à nouveau avant de redémarrer le serveur.

(Mods: j'ai essayé de mettre ce commentaire sur la meilleure réponse où il appartient, mais je n'ai pas assez de réputation.)

Chapelle de Mark
la source
12

Commande simple sur une ligne pour s'en débarrasser, tapez la commande ci-dessous dans le terminal,

ps -a

Cela répertoriera tous les processus, la vérification qui sont utilisés par Python et tapez la commande ci-dessous dans le terminal,

kill -9 (processID) 

Par exemple, tuer -9 33178

Aditya
la source
7

Vous pouvez également servir sur le port disponible le plus élevé suivant en faisant quelque chose comme ceci 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 vous devez faire la même chose pour d'autres utilitaires, cela peut être plus pratique comme 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

Configurez cela comme un exécutable avec le nom get-free-portet vous pouvez faire quelque chose comme ceci:

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

Ce n'est pas aussi fiable que l'approche native de Python car le script bash ne capture pas le port - un autre processus pourrait saisir le port avant votre processus (condition de concurrence critique) - mais peut quand même être assez utile lorsque vous utilisez un utilitaire qui ne fonctionne pas. t avoir une approche propre à essayer.

Chris Johnson
la source
6

Je suis nouveau sur Python, mais après mes brèves recherches, j'ai découvert que cela est typique des sockets liés. Il se trouve que le socket est toujours utilisé et que vous devrez peut-être attendre pour l'utiliser. Ou, vous pouvez simplement ajouter:

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

Cela devrait rendre le port disponible dans un délai plus court. Dans mon cas, il a rendu le port disponible presque immédiatement.

PoisonIvee
la source
4

Juste au cas où les solutions ci-dessus ne fonctionneraient pas:

  1. Obtenez le port que votre processus écoute:

    $ ps ax | grep python

  2. Tuez le processus

    $ kill PROCESS_NAME

user3305074
la source
3

J'ai un Raspberry Pi et j'utilise un serveur Web Python (en utilisant Flask). J'ai tout essayé ci-dessus, la seule solution est de fermer le terminal (shell) et de l'ouvrir à nouveau. Ou redémarrez le raspberry pi , car rien n'arrête ce serveur web ...

Thiago Farias
la source
2

Vous pouvez autoriser le serveur à réutiliser une adresse avec allow_reuse_address.

Indique si le serveur autorisera la réutilisation d'une adresse. Cette valeur par défaut est Falseet peut être définie dans des sous-classes pour modifier la stratégie.

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
la source