2011-12-14 17 views
5

मैं asyncore के साथ सरल async http ग्राहक करने की कोशिश: इस कोड को ठीक काम करता है और उत्पादन होता है (तेजी से enought):asyncore अजगर लटकी हुई है

www.gmail.com : recv http code: 301 
www.yandex.ru : recv http code: 200 
www.python.org : recv http code: 200 
www.google.ru : recv http code: 200 
www.gravatar.com : recv http code: 302 
www.com.com : recv http code: 302 
www.yahoo.com : recv http code: 302 
www.bom.com : recv http code: 301 

लेकिन से मैं मेजबान मौजूद नहीं के साथ टिप्पणी हटाएं लाइन:

#c = AsyncHTTP('http://www.no-such-host.ru') #!this line breaks execution! 

निष्पादन टूटता है, कोड कुछ समय के लिए लटका हुआ है, डेटा के उत्पादन में हिस्सा है और कोई अंतिम डेटा उत्पादन के साथ लटका हुआ है:

connection error: [Errno -5] No address associated with hostname 
www.gmail.com : recv http code: 301 
www.yandex.ru : recv http code: 200 
www.yahoo.com : recv http code: 302 
www.com.com : recv http code: 302 
www.bom.com : recv http code: 301 
www.gravatar.com : recv http code: 302 

... कुछ मेजबान यहां खो गए हैं और शुरुआत में देर हो चुकी हैं।

ऐसा क्यों होता है और इसे कैसे ठीक किया जाए?

# coding=utf-8 
import asyncore 
import string, socket 
import StringIO 
import mimetools, urlparse 

class AsyncHTTP(asyncore.dispatcher): 
    # HTTP requestor 

    def __init__(self, uri): 
     asyncore.dispatcher.__init__(self) 

     self.uri = uri 


     # turn the uri into a valid request 
     scheme, host, path, params, query, fragment = urlparse.urlparse(uri) 
     assert scheme == "http", "only supports HTTP requests" 
     try: 
      host, port = string.split(host, ":", 1) 
      port = int(port) 
     except (TypeError, ValueError): 
      port = 80 # default port 
     if not path: 
      path = "/" 
     if params: 
      path = path + ";" + params 
     if query: 
      path = path + "?" + query 

     self.request = "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n" % (path, host) 

     self.host = host 
     self.port = port 

     self.status = None 
     self.header = None 
     self.http_code = None 
     self.data = "" 

     # get things going! 
     self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
     #self.connect((host, port)) 
     #return 
     try: 
      self.connect((host, port)) 
     except Exception,e: 
      self.close() 
      self.handle_connect_expt(e) 

    def handle_connect(self): 
     self.send(self.request) 

    def handle_expt(self): 
     print "handle_expt error!" 
     self.close() 

    def handle_error(self): 
     print "handle_error error!" 
     self.close() 

    def handle_connect_expt(self,expt): 
     print "connection error:",expt 

    def handle_code(self):   
     print self.host," : ","recv http code: ",self.http_code 


    def handle_read(self): 
     data = self.recv(2048) 
     #print data 
     if not self.header: 
      self.data = self.data + data 
      try: 
       i = string.index(self.data, "\r\n\r\n") 
      except ValueError: 
       return # continue 
      else: 
       # parse header 
       fp = StringIO.StringIO(self.data[:i+4]) 
       # status line is "HTTP/version status message" 
       status = fp.readline() 
       self.status = string.split(status, " ", 2) 
       self.http_code = self.status[1] 
       self.handle_code()  

       # followed by a rfc822-style message header 
       self.header = mimetools.Message(fp) 
       # followed by a newline, and the payload (if any) 
       data = self.data[i+4:] 
       self.data = "" 
       #header recived 
       #self.close() 


    def handle_close(self): 
     self.close() 




c = AsyncHTTP('http://www.python.org') 
c = AsyncHTTP('http://www.yandex.ru') 
c = AsyncHTTP('http://www.google.ru') 
c = AsyncHTTP('http://www.gmail.com') 
c = AsyncHTTP('http://www.gravatar.com') 
c = AsyncHTTP('http://www.yahoo.com') 
c = AsyncHTTP('http://www.com.com') 
c = AsyncHTTP('http://www.bom.com') 
#c = AsyncHTTP('http://www.no-such-host.ru') #!this line breaks execution! 
asyncore.loop() 

ps: मेरा प्रणाली ubuntu 11.10 + अजगर 2.7.2

+0

अपनी लिपिक्स प्रणाली (उबंटू नहीं) पर अपनी स्क्रिप्ट का प्रयास किया, और यह आपके द्वारा रिपोर्ट की गई किसी भी समस्या के बिना चलता है। इसलिए संभवतः आपके उबंटू सेटअप के साथ कुछ समस्या होनी चाहिए। – ekhumoro

+0

@ekhumoro: मुझे खेद है, मैं भी इस कोड की कोशिश की और कोई समस्या के साथ काम कर रहा है :) – codersofthedark

उत्तर

4

आप एक अवरुद्ध नाम संकल्प आह्वान जब आप self.connect((host, port)) है। आपके स्थानीय DNS कॉन्फ़िगरेशन के साथ संयुक्त, इसीलिए आपके प्रोग्राम में स्टार्टअप में बहुत देर हो चुकी है।

एसिंककोर का एक विकल्प और गैर-अवरुद्ध नाम रिज़ॉल्यूशन स्वयं को कैसे करना है, यह पता लगाने के लिए, आप ट्विस्टेड का उपयोग करने के बारे में सोच सकते हैं। ट्विस्टेड टीसीपी कनेक्शन सेटअप एपीआई (मुख्य रूप से reactor.connectTCP या इसके शीर्ष पर बनाए गए एपीआई में से एक) ब्लॉक नहीं करता है। तो इसका एक बेवकूफ उपयोग ठीक से अतुल्यकालिक रहेगा।

संबंधित मुद्दे