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.


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.


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


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

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.)


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


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.


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.


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


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 ...


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()
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.