2015-03-23 26 views
6

Mam skrypt CherryPy, który często uruchamiam, aby uruchomić serwer. Dzisiaj musiałem zacząć i zatrzymać go kilka razy, aby naprawić błędy w pliku konfiguracyjnym, i myślę, że gniazdo nie zamknęło się całkowicie, ponieważ gdy próbowałem go uruchomić ponownie, dostałem ten problem:Błąd gniazda: Adres już w użyciu

[23/Mar/2015:14:08:00] ENGINE Listening for SIGHUP. 
[23/Mar/2015:14:08:00] ENGINE Listening for SIGTERM. 
[23/Mar/2015:14:08:00] ENGINE Listening for SIGUSR1. 
[23/Mar/2015:14:08:00] ENGINE Bus STARTING 
CherryPy Checker: 
The Application mounted at '' has an empty config. 

[23/Mar/2015:14:08:00] ENGINE Started monitor thread 'Autoreloader'. 
[23/Mar/2015:14:08:00] ENGINE Started monitor thread '_TimeoutMonitor'. 
[23/Mar/2015:14:08:00] ENGINE Error in HTTP server: shutting down 
Traceback (most recent call last): 
    File "/home/andrew/virtualenvs/mikernels/lib/python2.7/site-packages/cherrypy/process/servers.py", line 188, in _start_http_thread 
    self.httpserver.start() 
    File "/home/andrew/virtualenvs/mikernels/lib/python2.7/site-packages/cherrypy/wsgiserver/wsgiserver2.py", line 1848, in start 
    raise socket.error(msg) 
error: No socket could be created 

edytowany wsgiserver2.py CherryPy, aby zobaczyć szczegóły socket.error i error.strerror był

98 (98, 'Address already in use') Address already in use 

Tymczasem moje gniazdo jest skonstruowany jako:

af = 2 
socktype = 1 
proto = 6 
canonname = '' 
sa = ('0.0.0.0', 2112) 
self.bind(af, socktype, proto) 

(tha nie jest to dokładny kod, ale takie są wartości w momencie wystrzelenia błędu)

Sprawdziłem netstat i nie widziałem nic nasłuchującego na porcie 2112, co mogło być przyczyną problemu i jak mogę go zdiagnozować?

Dzięki!

Odpowiedz

14

Można wypróbować następujące

from socket import * 

sock=socket() 
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 
# then bind 

Od docs:

The SO_REUSEADDR flag tells the kernel to reuse a local socket in TIME_WAIT state, without waiting for its natural timeout to expire.

Oto pełna wyjaśnienie:

Running an example several times with too small delay between executions, could lead to this error:

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

This is because the previous execution has left the socket in a TIME_WAIT state, and can’t be immediately reused.

There is a socket flag to set, in order to prevent this, socket.SO_REUSEADDR:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
s.bind((HOST, PORT)) 
+0

Co to zrobi? –

+0

@AndrewLatham, zobacz zmiany w moim poście – ForceBru

+0

Dzięki, ale widzę w kodzie, który prowadzę, że CherryPy faktycznie to robi. Linia 1884: self.socket.setsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) Umieściłem polecenie print po tym wierszu, aby sprawdzić, czy nie zostało ono wykonane, ale wygląda na to, że jest. –

12

Można znaleźć proces i kill, wykonując:

ps aux | grep python 

znalezienie identyfikator procesu, a zatrzymanie go ręcznie, wykonując:

sudo kill -9 PID 

zastępując PID z PID.

Często muszę to robić podczas testów z Flask/CherryPy. Byłby zainteresowany, aby zobaczyć, czy istnieje prostszy sposób (na przykład, aby zapobiec w pierwszej kolejności)

+1

Czy nie byłoby łatwiej 'killall python' lub nawet' sudo killall python'? – ForceBru

+0

dziękuje Ryan za -9 –

+2

co oznacza -9? – kurumkan

9

Dużo łatwiej to zrobić przez:

Sprawdzić PID (: 5000 jest gospodarzem odkąd jestem uruchomiony na 127.0.0.1:5000):
$ lsof -i :5000
Następnie zabij:
$ sudo kill -9 PID