2013-10-16 13 views
7
è

Sto lavorando con un po 'di Python che assomiglia a questo:libreria socket Python pensa presa è aperta quando non

HOST = '127.0.0.1' 
PORT = 43434 
single = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
try: 
    single.bind((HOST, PORT)) 
except socket.error as e: 
    # Print an error, exit. 

Mentre è funzionato bene in passato, abbiamo ora ottenere l'errore [Errno 98] Address already in use. Il gestore SIGINT chiude la connessione socket, quindi non sono sicuro di come sia entrato in quello stato, ma per ora sto solo provando a sistemarlo.

Sia lsof e netstat dire non c'è niente che utilizza quella porta:

[$]> sudo netstat -an | grep 43434 
[$]> sudo lsof -i :43434 

TIME_WAIT è impostato a 60 secondi, secondo /proc/sys/net/ipv4/tcp_fin_timeout, ma l'errore si verifica anche ore dopo l'ultima corsa con successo.

Ho provato (temporaneamente) l'impostazione REUSEADDR (tramite single.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)), ma sembra non avere alcun effetto.

Cosa sta succedendo? Potrò mai utilizzare nuovamente questa porta senza dover riavviare la macchina?

+1

Hai chiamato 'setsockopt' prima chiamata' bind'? –

+0

@WaleedKhan Yep; è andato subito prima del 'try'. –

risposta

0

Prova questo:
tcpkill -i eth0 porta 43434

+0

L'esecuzione di tcpkill (che si trova nel pacchetto dsniff, btw), si blocca su 'tcpkill: ascolto su eth0 [porta 43434]'. Ho provato a farlo funzionare con '-9', stessa cosa. –

+0

Ho anche provato a usare 'cxkill', che non riportava alcuna connessione su quella porta. E sto tentando di usare 'cutter', ma [ci sono problemi] (http://stackoverflow.com/q/11581814/120999) che ottengono quello in esecuzione su CentOS. –

0

Si potrebbe provare a impostare SO_REUSEPORT opzioni socket. Tuttavia, funziona solo se il socket in conflitto aveva anche le opzioni SO_REUSEPORT impostate prima del suo binding, quindi dovresti provare dopo un riavvio pulito.

Tuttavia, hai detto che il tuo codice Python assomiglia al codice che hai postato. Hai provato una versione molto semplificata del tuo programma per testare solo il binding?

Puoi anche provare a stracellare il tuo programma.

1

Volevo aggiungere un commento ma non me lo consente di farlo. quindi devo rispondere in questo modo. Nella mia esperienza ho dovuto fare quanto segue per far funzionare le prese con successo. Ho dovuto impostare in modo esplicito il timeout.

Nel codice prima di aprire il socket, è necessario impostarlo se si utilizza Python versione 2.3 o successiva. Di solito inizio con un timeout di 30 secondi e poi lo sintonizzo su ciò che funziona per un determinato sito web. Quando non uso questo parametro ottengo problemi di flakey.

socket.setdefaulttimeout(timeout) 

Altre questioni che ho fatto dopo l'apertura sono catturare alcuni dei seguenti eccezioni:

  except socket.gaierror, err: 
       # you might want to handle this 
      except socket.sslerror, err2: 
       # you might want to handle this if doing SSL 
Problemi correlati