socket.error: [Erro 48] Endereço já em uso

224

Eu estou tentando configurar um servidor com python do terminal mac.

Navego para o local da pasta e uso:

python -m SimpleHTTPServer

Mas isso me dá erro:

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

Eu já havia aberto uma conexão usando o mesmo comando para um site diferente em um local diferente na minha máquina.

irmãos
fonte
2
Mate o outro processo ou execute este com uma porta diferente:python -m SimpleHTTPServer 8081
Blender

Respostas:

356

Você já tem um processo vinculado à porta padrão (8000). Se você já executou o mesmo módulo antes, é mais provável que o processo ainda esteja vinculado à porta. Tente e localize o outro processo primeiro:

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

Os argumentos do comando estão incluídos, para que você possa identificar o que está sendo executado SimpleHTTPServerse mais de um pythonprocesso estiver ativo. Você pode querer testar se http://localhost:8000/ainda mostra uma lista de diretórios para arquivos locais.

O segundo número é o número do processo; pare o servidor enviando um sinal para ele:

kill 81651

Isso envia um SIGTERMsinal padrão ; se o processo não responder, talvez seja necessário recorrer a métodos mais difíceis, como enviar um sinal SIGKILL( kill -s KILL <pid>ou kill -9 <pid>). Veja a Wikipedia para mais detalhes .

Como alternativa, execute o servidor em uma porta diferente , especificando a porta alternativa na linha de comandos:

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

depois acesse o servidor como http://localhost:8910; onde 8910pode haver qualquer número entre 1024 e superior, desde que a porta ainda não esteja ocupada.

Martijn Pieters
fonte
Qual URL devo ter no navegador para ver se está funcionando? Estou correndo em uma porta diferente, como você sugested
irm
14
pode precisar usarsudo kill -9 PID
Danpe
Obrigado, @Danpe, tentei "sudo kill PID", que não funcionou, mas "sudo kill -9 PID" matou o processo. Alguém sabe o que -9 especifica? Mesmo sudo manual não parecem cobrir este parâmetro sudo.ws/man/sudo.man.html
seokhoonlee
3
@seokhoonlee: killenvia um sinal ao processo, com o qual ele pode decidir lidar (como desligar normalmente ou girar um arquivo de log). Esses sinais são números inteiros (cada um com um nome), o padrão sendo 15, significando TERMou terminando . O uso de -9 envia o sinal 9, KILLque um processo não pode capturar e ignorar, e o sistema operacional encerrará o processo se quiser ou não.
Martijn Pieters
@seokhoonlee: veja também o artigo de sinal Unix na Wikipedia.
Martijn Pieters
153

Solução simples:

  1. Encontre o processo usando a porta 8080:

    sudo lsof -i:8080

  2. Mate isso:

    kill XXXX

Caracol
fonte
8
Esta resposta se beneficiaria de um exemplo de como a lsofsaída pode ser e como encontrar o ID do processo (o "XXXX" que você lista) na saída. Para quem vê isso sem essas informações, é o segundo campo na saída, sob um rótulo de cabeçalho "PID".
Lindes
2
@ Lindes Você é um crack!
Carlos Rodríguez
@ CarlosRodríguez: hein? Eu realmente não sei o que você quer dizer com o comentário (eu sei múltiplas definições de "crack", e os que eu conheço não parecem se encaixar ...)
lindes
2
@ CarlosRodríguez Eu quero acreditar que ele encontrou sua resposta absolutamente certa. Penso que a sua observação sobre a necessidade de fornecer amostras da saída de lsof e como identificar o PID é muito importante. O segundo item em cada linha retornada é geralmente o PID, ele está sempre na coluna PID da saída
Kudehinbu Oluwaponle 04/04/19
32

Usar

 sudo lsof -i:5000

Isso fornecerá uma lista de processos usando a porta, se houver. Depois que a lista de processos for fornecida, use o ID na coluna PID para finalizar o processo.

 kill 379 #use the provided PID
candy_man
fonte
Isso é perfeito, especialmente aqueles que trabalham em MAC OSX e não usar SO_REUSEPORT vez de SO_REUSEADDR
snr
16

A propósito, para impedir que isso aconteça, basta pressionar Ctrl+C no terminal enquanto o SimpleHTTPServer ainda está funcionando normalmente. Isso irá "corretamente" parar o servidor e liberar a porta para que você não precise encontrar e matar o processo novamente antes de reiniciar o servidor.

(Mods: Eu tentei colocar esse comentário na melhor resposta aonde ele pertence, mas não tenho reputação suficiente.)

Mark Chapel
fonte
12

Comando simples de uma linha para se livrar dele, digite o comando abaixo no terminal,

ps -a

Isso listará todos os processos, check-out que está sendo usado pelo Python e digite o comando abaixo no terminal,

kill -9 (processID) 

Por exemplo, kill -9 33178

Aditya
fonte
7

Você também pode servir na próxima porta mais alta disponível, fazendo algo assim no 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 você precisar fazer o mesmo com outros utilitários, pode ser mais conveniente como um 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 isso como um executável com o nome get-free-porte você pode fazer algo assim:

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

Isso não é tão confiável quanto a abordagem nativa do Python, porque o script bash não captura a porta - outro processo pode pegar a porta antes do seu processo (condição de corrida) - mas ainda pode ser útil o suficiente ao usar um utilitário que não ' Não tenha uma abordagem própria, tente novamente.

Chris Johnson
fonte
6

Eu sou novo no Python, mas após minha breve pesquisa, descobri que isso é típico de soquetes sendo vinculados. Acontece que o soquete ainda está sendo usado e você pode ter que esperar para usá-lo. Ou você pode simplesmente adicionar:

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

Isso deve disponibilizar a porta em menos tempo. No meu caso, disponibilizou a porta quase imediatamente.

PoisonIvee
fonte
4

Caso as soluções acima não funcionassem:

  1. Obtenha a porta que seu processo está ouvindo:

    $ ps ax | grep python

  2. Mate o processo

    $ kill PROCESS_NAME

user3305074
fonte
3

Eu tenho um pi raspberry e estou usando um servidor web python (usando o Flask). Eu tentei de tudo acima, a única solução é fechar o terminal (shell) e abri-lo novamente. Ou reinicie o raspberry pi , porque nada impede o servidor da web ...

Thiago Farias
fonte
2

Você pode permitir que o servidor reutilize um endereço allow_reuse_address.

Se o servidor permitirá a reutilização de um endereço. O padrão é Falsee pode ser definido nas subclasses para alterar a 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
fonte