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.