2014-11-09 18 views
7

ho il seguente codice per eseguire un ciclo continuo per andare a prendere alcuni contenuti da un sito web:python3 urllib.request non chiuderà le connessioni immediatamente

from http.cookiejar import CookieJar 
from urllib import request 

cj = CookieJar() 
cp = request.HTTPCookieProcessor(cj) 
hh = request.HTTPHandler() 
opener = request.build_opener(cp, hh) 

while True: 
    # build url 
    req = request.Request(url=url) 
    p = opener.open(req) 
    c = p.read() 
    # process c 
    p.close() 
    # check for abort condition, or continue 

I contenuti siano correttamente lette. Ma per qualche ragione, le connessioni TCP non si chiuderanno. Sto osservando il conteggio delle connessioni attivo da un'interfaccia del router dd-wrt e sale costantemente. Se lo script continua a funzionare, esaurirà il limite di 4096 connessioni del router. Quando ciò accade, lo script entra semplicemente nello stato di attesa (il router non consentirà nuove connessioni, ma il timeout non ha ancora colpito). Dopo un paio di minuti, tali connessioni verranno chiuse e lo script potrà riprendere nuovamente.

Sono stato in grado di osservare lo stato di quelle connessioni pendenti dal router. Condividono lo stesso stato: TIME_WAIT.

Mi aspetto che questo script non usi più di 1 connessione TCP contemporaneamente. Che cosa sto facendo di sbagliato?

Sto usando Python 3.4.2 su Mac OS X 10.10.

+1

Questo potrebbe aiutare: http://stackoverflow.com/questions/5442291/close-urllib2-connection – Eric

risposta

4

Attraverso alcune ricerche, ho scoperto la causa di questo problema: the design of TCP protocol. In poche parole, quando si disconnette, la connessione non viene eliminata immediatamente, entra nello stato "TIME_WAIT" e si interrompe dopo 4 minuti. A differenza di quanto mi aspettavo, la connessione non scompare immediatamente.

In base a this question, non è inoltre possibile rilasciare forzatamente una connessione (senza riavviare lo stack di rete).

Nel mio caso particolare, come this question stated, un'opzione migliore sarebbe utilizzare una connessione persistente, a.k.a HTTP keep-alive. Come sto interrogando lo stesso server, funzionerà.

Problemi correlati