2011-12-15 1 views
4

단순한 비동기 http 클라이언트는 사용할 수없는 사이트에서 오랫동안 중단됩니다.asyncore timeout

예를 들어 사이트 www.evtur.ru에서 오랜 시간, 10 분 이상 기다립니다.

시간 제한을 최소화하는 방법을 찾지 못했습니다. 예를 들어 5 초 내에 시간 초과를 할 수 있습니까?

# 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.evtur.ru') 
asyncore.loop(timeout=0.05) 
+0

코드에 형식이 필요하다고 생각합니다. 탭과 스페이스를 혼합하고 있습니까? 그렇다면 이것은 잘못된 생각입니다. http://www.python.org/dev/peps/pep-0008/ – Wilduck

+0

이 주제에 대한 다른 질문으로 [이 답변] (http://stackoverflow.com/a/8513221/984421)에서 설명했듯이 문제는 코드가 아니라 시스템 설정과 관련됩니다. – ekhumoro

+0

가능한 복제본 [asyncore python hangs] (http://stackoverflow.com/questions/8504518/asyncore-python-hangs) – ekhumoro

답변

0

디스패처 소켓에서 시간 초과를 설정해야합니다.

self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 

를 호출 한 후에는

self.socket.settimeout(nn) 

소켓에 타임 아웃을 설정하기 위해 호출 할 수 있습니다. 다른 소켓과 마찬가지로 다른 소켓 옵션도 설정할 수 있습니다.

1
self.socket.settimeout(nn) 

이것은 나를 위해 작동하지 않는 것 같습니다.

그러나 asyncore.loop()에는 count라는 매개 변수가 있습니다. 5 초를 원한다면, 당신이 할 필요가

for i in range(count): 
    ... 
    select(... , timeout) 
    ... 

: 여기서 뭐하는 의사 코드 무엇 asyncore.loop()이다

asyncore.loop(timeout=1, count=5) 

그러나 정확한 방법으로 작업을하지 않는 것이 좋습니다. "이벤트"가있는 경우 5 개 이상의 "개수"가있을 수 있습니다. 다음 코드를 사용합니다.

start = int(time.time()) 

while True: 
    asyncore.loop(timeout=1, count=5) 
    print "LOOP : %d enqueued, waiting to finish" % len(asyncore.socket_map) 

    if len(asyncore.socket_map) == 0 : 
     break 

    if int(time.time()) - start > timeout : 
     print "LOOP : Timeout" 
     break