2009-05-01 10 views
8

कनेक्शन पाखंड के मामले में मेरे पायथन अनुप्रयोगों में से एक को और अधिक मजबूत बनाने की कोशिश करते समय मुझे पता चला कि urllib2 द्वारा बनाए गए http-stream के पढ़ने के फ़ंक्शन को कॉल करना ब्लॉक हो सकता है हमेशा के लिए लिपि।urllib2 द्वारा बनाई गई स्ट्रीम को पढ़ने से कभी भी ठीक नहीं हो जाता है जब कनेक्शन बाधित हो जाता है

मैंने सोचा कि पढ़ा गया कार्य समय-समय पर समाप्त हो जाएगा और अंततः एक अपवाद उठाएगा, लेकिन जब यह एक फंक्शन फ़ंक्शन कॉल के दौरान कनेक्शन बाधित हो जाता है तो यह मामला नहीं है।

यहाँ कोड है कि समस्या का कारण होगा है:

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" 

(आप स्क्रिप्ट आप शायद स्क्रिप्ट कभी नहीं ठीक है जहाँ से आप इससे पहले कि आप राज्य तक पहुंच जाएगा कनेक्शन कई बार बाधित करने के लिए की जरूरत है बाहर का प्रयास करें)

मैंने स्क्रिप्ट को Winpdb के माध्यम से देखा और उस राज्य का एक स्क्रीनशॉट बनाया जहां से स्क्रिप्ट कभी ठीक नहीं होती है (भले ही नेटवर्क फिर से उपलब्ध हो)।

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

वहाँ एक अजगर स्क्रिप्ट है कि विश्वसनीय काम करने के लिए भले ही नेटवर्क कनेक्शन बाधित हो गया जारी रहेगा बनाने के लिए एक तरीका है? (मैं इसे अतिरिक्त थ्रेड के अंदर करने से बचना पसंद करूंगा।)

+0

एक अच्छी तरह से लिखा सवाल –

उत्तर

6
कुछ

प्रयास करें की तरह:

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

ऐसा लगता है कि यह मेरी समस्या हल हो गया है। धन्यवाद! – Martin

+0

यह काम करता है, सिवाय इसके कि यह [बग 6056] (http://bugs.python.org/issue6056) के कारण मल्टीप्रोसेसिंग को खराब करता है। सॉकेट के डिफ़ॉल्ट टाइमआउट को प्रभावित किए बिना urllib2 पर टाइमआउट जोड़ने का कोई और तरीका है? – UsAaR33

2

अच्छा सवाल, मुझे वास्तव में एक जवाब खोजने में दिलचस्पी होगी। एकमात्र कामकाज मैं सोच सकता था कि python docs में सिग्नल चाल का उपयोग कर रहा है। आपके मामले में यह हो जाएगा अधिक की तरह:

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 
+0

मेरे लिए बहुत आशाजनक लेकिन अभ्यस्त काम लग रहा है कि के बाद से मैं काम कर रहा हूँ के लिए +1 एक विंडोज पीसी पर। – Martin

+0

आह, मैं देखता हूं। हालांकि एलेक्स का समाधान वादा करता है। –