socket.error: [Errno 48] Alamat sudah digunakan

224

Saya mencoba mengatur server dengan python dari terminal mac.

Saya menavigasi ke lokasi folder yang digunakan:

python -m SimpleHTTPServer

Tapi ini memberi saya kesalahan:

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

Saya sebelumnya telah membuka koneksi menggunakan perintah yang sama untuk situs web yang berbeda di lokasi yang berbeda di mesin saya.

konfirmasi
sumber
2
Bunuh proses lainnya atau jalankan yang ini dengan port yang berbeda:python -m SimpleHTTPServer 8081
Blender

Jawaban:

356

Anda sudah memiliki proses yang terikat ke port default (8000). Jika Anda sudah menjalankan modul yang sama sebelumnya, kemungkinan besar proses itu masih terikat ke port. Coba dan cari proses lain terlebih dahulu:

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

Argumen perintah disertakan, sehingga Anda dapat melihat yang berjalan SimpleHTTPServerjika lebih dari satu pythonproses aktif. Anda mungkin ingin menguji apakah http://localhost:8000/masih menampilkan daftar direktori untuk file lokal.

Angka kedua adalah nomor proses; hentikan server dengan mengirimkannya sinyal:

kill 81651

Ini mengirimkan SIGTERMsinyal standar ; jika prosesnya tidak responsif, Anda mungkin harus menggunakan metode yang lebih keras seperti mengirim sinyal SIGKILL( kill -s KILL <pid>atau kill -9 <pid>). Lihat Wikipedia untuk lebih jelasnya .

Atau, jalankan server pada port yang berbeda , dengan menentukan port alternatif pada baris perintah:

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

kemudian akses server sebagai http://localhost:8910; di mana 8910bisa nomor dari 1024 ke atas, asalkan port belum diambil.

Martijn Pieters
sumber
URL apa yang harus saya miliki di browser untuk melihat apakah itu berfungsi? Saya menjalankan pada port yang berbeda saat Anda menyarankan
irm
14
mungkin perlu menggunakansudo kill -9 PID
Danpe
Terima kasih, @Danpe, saya mencoba "sudo kill PID" yang tidak berhasil tetapi "sudo kill -9 PID" membunuh prosesnya. Adakah yang tahu apa yang ditentukan -9? Bahkan manual sudo tampaknya tidak mencakup parameter ini sudo.ws/man/sudo.man.html
seokhoonlee
3
@ seokhoonlee: killmengirimkan sinyal ke proses, yang dapat diputuskan untuk ditangani (seperti mematikan dengan anggun atau memutar file log). Sinyal-sinyal ini adalah bilangan bulat (masing-masing dengan nama), defaultnya adalah 15, artinya TERMatau berakhir . Menggunakan -9 mengirimkan sinyal 9,, KILLyang prosesnya tidak dapat tangkap dan abaikan, dan OS akan mengakhiri proses apakah suka atau tidak.
Martijn Pieters
@ seokhoonlee: lihat juga artikel sinyal Unix di Wikipedia.
Martijn Pieters
153

Solusi sederhana :

  1. Temukan proses menggunakan port 8080:

    sudo lsof -i:8080

  2. Bunuh itu:

    kill XXXX

Siput
sumber
8
Jawaban ini akan mendapat manfaat dari contoh seperti apa lsofoutput itu, dan bagaimana menemukan ID proses ("XXXX" daftar Anda) dalam output. Bagi siapa pun yang melihat ini tanpa informasi itu, itu adalah bidang kedua dalam output, di bawah label header "PID".
lindes
2
@lindes Anda seorang crack!
Carlos Rodríguez
@ CarlosRodríguez: ya? Saya benar-benar tidak tahu apa yang Anda maksud dengan komentar itu (saya tahu banyak definisi "crack", dan yang saya tahu sepertinya tidak cocok ...)
lindes
2
@ CarlosRodríguez Saya ingin percaya dia menemukan jawaban Anda benar-benar tepat. Saya pikir pengamatan Anda tentang perlunya memberikan sampel output lsof dan bagaimana mengidentifikasi PID sangat penting. Item kedua di setiap baris yang dikembalikan biasanya PID, selalu di bawah kolom PID output
Kudehinbu Oluwaponle
33

Menggunakan

 sudo lsof -i:5000

Ini akan memberi Anda daftar proses menggunakan port jika ada. Setelah daftar proses diberikan, gunakan id pada kolom PID untuk mengakhiri penggunaan proses

 kill 379 #use the provided PID
Manusia permen
sumber
Yang sempurna, terutama yang bekerja di MAC OSX dan tidak menggunakan SO_REUSEPORT bukan SO_REUSEADDR
SNR
16

By the way, untuk mencegah hal ini terjadi di tempat pertama, cukup tekan Ctrl+ Cdi terminal saat SimpleHTTPServer masih berjalan normal. Ini akan "benar" menghentikan server dan melepaskan port sehingga Anda tidak perlu menemukan dan mematikan proses lagi sebelum me-restart server.

(Mods: Saya memang mencoba memberikan komentar ini pada jawaban terbaik di mana tempatnya, tetapi saya tidak memiliki reputasi yang cukup.)

Mark Chapel
sumber
12

Perintah sederhana satu baris untuk menghilangkannya, ketik perintah di bawah ini di terminal,

ps -a

Ini akan mencantumkan semua proses, checkout yang sedang digunakan oleh Python dan ketik perintah di bawah di terminal,

kill -9 (processID) 

Misalnya membunuh -9.317.18

Aditya
sumber
7

Anda juga dapat melayani di port tertinggi berikutnya yang tersedia melakukan sesuatu seperti ini di 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

Jika Anda perlu melakukan hal yang sama untuk utilitas lain, mungkin lebih nyaman sebagai skrip 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

Tetapkan itu sebagai yang dapat dieksekusi dengan nama get-free-portdan Anda dapat melakukan sesuatu seperti ini:

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

Itu tidak dapat diandalkan seperti pendekatan Python asli karena skrip bash tidak menangkap port - proses lain bisa mengambil port sebelum proses Anda lakukan (kondisi ras) - tetapi masih mungkin cukup berguna ketika menggunakan utilitas yang tidak Saya tidak memiliki pendekatan coba-coba sendiri.

Chris Johnson
sumber
6

Saya baru mengenal Python, tetapi setelah penelitian singkat saya menemukan bahwa ini adalah khas dari soket yang diikat. Kebetulan bahwa soket masih digunakan dan Anda mungkin harus menunggu untuk menggunakannya. Atau, Anda bisa menambahkan:

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

Ini harus membuat port tersedia dalam waktu yang lebih singkat. Dalam kasus saya, itu membuat port tersedia segera.

PoisonIvee
sumber
4

Untuk berjaga-jaga jika solusi di atas tidak berhasil:

  1. Dapatkan port yang prosesnya Anda dengarkan:

    $ ps kapak | grep python

  2. Bunuh Prosesnya

    $ kill PROCESS_NAME

pengguna3305074
sumber
3

Saya punya pi raspberry, dan saya menggunakan server web python (menggunakan Flask). Saya sudah mencoba semuanya di atas, satu-satunya solusi adalah dengan menutup terminal (shell) dan membukanya lagi. Atau mulai ulang pi raspberry , karena tidak ada yang menghentikan server web itu ...

Thiago Farias
sumber
2

Anda dapat mengizinkan server untuk menggunakan kembali suatu alamat allow_reuse_address.

Apakah server akan mengizinkan penggunaan kembali suatu alamat. Ini default ke False, dan dapat diatur dalam subkelas untuk mengubah kebijakan.

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
sumber