la lettura di uno stream creato da urllib2 non ripristina mai quando la connessione è stata interrotta

StackOverflow https://stackoverflow.com/questions/811446

  •  03-07-2019
  •  | 
  •  

Domanda

Durante il tentativo di rendere una delle mie applicazioni Python un po 'più robusta in caso di interruzioni della connessione, ho scoperto che chiamare la funzione di lettura di un flusso http creato da urllib2 potrebbe bloccare lo script per sempre.

Ho pensato che la funzione di lettura andrà in timeout e alla fine genererà un'eccezione, ma questo non sembra essere il caso in cui la connessione è stata interrotta durante una chiamata della funzione di lettura.

Ecco il codice che causerà il problema:

import urllib2

while True:
    try:
        stream = urllib2.urlopen('http://www.google.de/images/nav_logo4.png')
        while stream.read(): pass
        print "Done"
    except:
        print "Error"

(Se si prova lo script, probabilmente è necessario interrompere la connessione più volte prima di raggiungere lo stato dal quale lo script non viene mai ripristinato)

Ho guardato lo script tramite Winpdb e ho creato uno screenshot dello stato dal quale lo script non si ripristina mai (anche se la rete è nuovamente disponibile).

Winpdb http://img10.imageshack.us/img10/6716/urllib2.jpg

Esiste un modo per creare uno script Python che continuerà a funzionare in modo affidabile anche se la connessione di rete viene interrotta? (Preferirei evitare di farlo all'interno di un thread aggiuntivo.)

È stato utile?

Soluzione

Prova qualcosa del tipo:

import socket
socket.setdefaulttimeout(5.0)
   ...
try:
   ...
except socket.timeout:
   (it timed out, retry)

Altri suggerimenti

Bella domanda, sarei davvero interessato a trovare una risposta. L'unica soluzione che mi è venuta in mente è usare il trucco del segnale spiegato in python docs . Nel tuo caso sarà più simile a:

import signal
import urllib2

def read(url):
    stream = urllib2.urlopen(url)
    return stream.read()

def handler(signum, frame):
    raise IOError("The page is taking too long to read")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This read() may hang indefinitely
try:
    output = read('http://www.google.de/images/nav_logo4.png')
except IOError:
    # try to read again or print an error
    pass

signal.alarm(0)          # Disable the alarm
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top