【问题标题】:asyncore timeout异步超时
【发布时间】:2013-04-06 03:30:39
【问题描述】:

简单的异步 http 客户端,在没有可用站点的情况下长时间挂起。

例如,在 www.evtur.ru 网站上,它会等待很长时间,十分钟或更长时间。

我找不到如何最小化超时的方法,例如是否可以在 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)

【问题讨论】:

  • 我认为您的代码需要一些格式。你在混合制表符和空格吗?如果是这样,这是一个坏主意。 python.org/dev/peps/pep-0008
  • 正如this answer 对您关于此主题的其他问题的解释,问题不在于您的代码,而在于您的系统设置。
  • asyncore python hangs的可能重复
  • 不,这个问题是不同的(只有相同的代码)。这里的问题不在 dns 调用阻塞中。站点访问中的问题(长时间没有服务器响应),我通过异步搜索使用非阻塞套接字最小化超时,这可能吗?

标签: python timeout asyncore


【解决方案1】:
self.socket.settimeout(nn)

这似乎不适合我。

但是,asyncore.loop() 有一个叫做 count 的参数。这是 asyncore.loop() 所做的伪代码:

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

所以如果你想要 5 秒,你需要这样做:

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

【讨论】:

    【解决方案2】:

    您必须在调度程序套接字上设置超时。 调用后

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

    你可以打电话

    self.socket.settimeout(nn)
    

    在套接字上设置超时。您还可以像设置任何其他套接字一样设置任何其他套接字选项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      • 1970-01-01
      • 2011-06-15
      • 2018-05-21
      • 2011-08-19
      • 1970-01-01
      相关资源
      最近更新 更多