socket.error: [Errno 48] Adres zaten kullanılıyor


224

Mac terminalinden python ile bir sunucu kurmaya çalışıyorum.

Klasör konumuna bir kullanım gidin:

python -m SimpleHTTPServer

Ama bu bana hata veriyor:

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

Daha önce makinemdeki farklı bir konumda farklı bir web sitesi için aynı komutu kullanarak bir bağlantı açmıştım.


2
Diğer işlemi öldür veya bu işlemi farklı bir limanla yap:python -m SimpleHTTPServer 8081
Blender

Yanıtlar:


356

Varsayılan bağlantı noktasına (8000) bağlı bir işleminiz zaten var. Daha önce aynı modülü çalıştırdıysanız, bu işlem büyük olasılıkla bağlantı noktasına bağlıdır. Önce diğer işlemi bulmaya çalışın:

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

Komut bağımsız değişkenleri dahil edilir, böylece SimpleHTTPServerbirden fazla pythonişlem etkinse çalışmakta olanı belirleyebilirsiniz . http://localhost:8000/Hala yerel dosyalar için bir dizin listesi gösterip göstermediğini test etmek isteyebilirsiniz .

İkinci sayı işlem numarasıdır; bir sinyal göndererek sunucuyu durdurun:

kill 81651

Bu standart bir SIGTERMsinyal gönderir ; işlem yanıt vermiyorsa, bunun yerine SIGKILL( kill -s KILL <pid>veya kill -9 <pid>) sinyal gönderme gibi daha zorlu yöntemlere başvurmanız gerekebilir . Daha fazla ayrıntı için Wikipedia'ya bakın .

Alternatif olarak, komut satırında alternatif bağlantı noktasını belirterek sunucuyu farklı bir bağlantı noktasında çalıştırın :

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

daha sonra sunucuya şu şekilde erişin http://localhost:8910; burada 8910bağlantı noktası önceden alınmamışsa 1024 ve üstü arasında herhangi bir sayı olabilir.


Çalışıp çalışmadığını görmek için tarayıcıda hangi URL'ye sahip olmalıyım? Eğer sugested gibi farklı bir bağlantı noktasında koşuyorum
IRM

14
gerekebilirsudo kill -9 PID
Danpe

Teşekkürler, @ Danpe, ben "sudo kill-9 PID" işe yaramadı "sudo kill PID" denedim. -9'un ne belirttiğini bilen var mı? Sudo
seokhoonlee

3
@seokhoonlee: killişleme, işlemeye karar verebileceği bir sinyal gönderir (incelikle kapat veya bir günlük dosyasını döndürmek gibi). Bu sinyaller tamsayılardır (her biri bir ada sahip), varsayılan değer 15, anlam TERMveya sonlandır . -9 kullanılması KILL, bir işlemin yapamadığı 9 sinyalini gönderir yakalamak ve görmezden ve ya da olmamak sever Hava OS sürecini sona erecek.
Martijn Pieters

@seokhoonlee: ayrıca bkz. Wikipedia'daki Unix sinyal makalesine.
Martijn Pieters

154

Basit çözüm :

  1. Bağlantı noktasını kullanarak işlemi bulun 8080:

    sudo lsof -i:8080

  2. Öldür:

    kill XXXX


8
Bu yanıt, lsofçıktının neye benzeyebileceğine ve çıktıdaki işlem kimliğinin (listelediğiniz "XXXX") nasıl bulunacağına ilişkin bir örnekten yararlanır . Bunu bu bilgi olmadan gören herkes için, çıktıdaki "PID" başlık etiketi altındaki ikinci alandır.
lindes

2
@lindes Sen bir çatlaksın!
Carlos Rodríguez

@ CarlosRodríguez: ha? Bu yorumla ne demek istediğini gerçekten bilmiyorum ("çatlak" ın birden fazla tanımını biliyorum ve bildiğim şeyler uymuyor gibi görünüyor ...)
lindes

2
@ CarlosRodríguez Yanıtınızı kesinlikle yerinde bulduğuna inanmak istiyorum. Bence lsof çıktısının örneklerini verme ihtiyacı ve PID'nin nasıl tanımlanacağı konusundaki gözleminiz çok önemlidir. Döndürülen her satırdaki ikinci öğe genellikle
PID'dir

33

kullanım

 sudo lsof -i:5000

Bu, varsa bağlantı noktasını kullanan işlemlerin bir listesini verecektir. İşlem listesi verildiğinde, işlem kullanımını sonlandırmak için PID sütunundaki kimliği kullanın

 kill 379 #use the provided PID

Bu, özellikle MAC OSX üzerinde çalışanlar ve SO_REUSEADDR yerine SO_REUSEPORT kullanmayanlar
snr

16

Bu arada, bunun olmasını önlemek için, SimpleHTTPServer hala normal çalışırken terminalde Ctrl+ tuşuna basın C. Bu, sunucuyu "düzgün bir şekilde" durdurur ve bağlantı noktasını serbest bırakır, böylece sunucuyu yeniden başlatmadan önce işlemi bulup öldürmeniz gerekmez.

(Mods: Bu yorumu ait olduğu en iyi yanıta koymaya çalıştım, ancak yeterince itibarım yok.)


12

Ondan kurtulmak için basit bir satır komutu, terminalde aşağıdaki komutu yazın,

ps -a

Bu, Python tarafından kullanılan tüm işlemleri, kasayı ve terminalde feryat komutunu listeleyecektir,

kill -9 (processID) 

Örneğin öldürmek -9 33178


7

Python'da şu şekilde bir şey yaparak bir sonraki en yüksek bağlantı noktasında da hizmet verebilirsiniz:

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

Diğer yardımcı programlar için aynı şeyi yapmanız gerekiyorsa, bir bash betiği olarak daha uygun olabilir:

#!/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

Bunu adıyla bir yürütülebilir dosya olarak ayarlayın get-free-portve böyle bir şey yapabilirsiniz:

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

Bu, yerel Python yaklaşımı kadar güvenilir değildir, çünkü bash betiği bağlantı noktasını yakalamaz - başka bir işlem işleminizden önce bağlantı noktasını yakalayabilir (yarış durumu) - ancak yine de yapmayan bir yardımcı program kullanırken yeterince yararlı olabilir. kendi kendine bir yeniden dene yaklaşımına sahip olmak.


6

Python'da yeniyim, ancak kısa araştırmamdan sonra bunun tipik olarak soketlerin bağlandığını öğrendim. Sadece soket hala kullanılıyor ve kullanmak için beklemek zorunda kalabilirsiniz. Veya şunları ekleyebilirsiniz:

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

Bu, bağlantı noktasını daha kısa sürede kullanılabilir hale getirmelidir. Benim durumumda, limanı neredeyse anında kullanılabilir hale getirdi.


4

Yukarıdaki çözümlerin işe yaramadığı durumlarda:

  1. İşleminizin dinlediği bağlantı noktasını alın:

    $ ps balta | grep python

  2. Süreci Öldür

    $ PROCESS_NAME öldür


3

Bir ahududu pi var ve ben (Flask kullanarak) python web sunucusu kullanıyorum. Yukarıdaki her şeyi denedim, tek çözüm terminali (kabuğu) kapatmak ve tekrar açmaktır. Veya ahududu pi'yi yeniden başlatın , çünkü hiçbir şey bu web sunucusunu durdurmaz ...


2

Sunucunun bir adresi yeniden kullanmasına izin verebilirsiniz allow_reuse_address .

Sunucunun bir adresin yeniden kullanılmasına izin verip vermeyeceği. Bu varsayılan Falsedeğerdir ve ilkeyi değiştirmek için alt sınıflara ayarlanabilir.

import SimpleHTTPServer, SocketServer
PORT = 8000
httpd = SocketServer.TCPServer(("", PORT), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.allow_reuse_address = True
print "Serving at port", PORT
httpd.serve_forever()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.