生成asyncore.dispatcher对象时如何跳过坏主机?

时间:2013-11-13 06:05:58

标签: python asyncore

import asyncore

class HTTPClient(asyncore.dispatcher):

    def __init__(self, host, path):
        asyncore.dispatcher.__init__(self)
        self.create_socket()
        self.connect( (host, 80) )
        self.buffer = bytes('GET %s HTTP/1.0\r\nHost: %s\r\n\r\n' %
                            (path, host), 'ascii')

    def handle_connect(self):
        pass

    def handle_close(self):
        self.close()

    def handle_read(self):
        print(self.recv(8192))

    def writable(self):
        return (len(self.buffer) > 0)

    def handle_write(self):
        sent = self.send(self.buffer)
        self.buffer = self.buffer[sent:]


client = HTTPClient('www.bocaonews.com.br', '/')
asyncore.loop()

提出了一个错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "***.py", line 15, in __init__
    self.connect( (host, 80) )
  File "***\lib\asyncore.py", line 339, in connect
    err = self.socket.connect_ex(address)
socket.gaierror: [Errno 11004] getaddrinfo failed

HTTP客户端是官方文档的示例。由于无法访问主机www.bocaonews.com.br,因此引发了错误。

所以我的问题是如何修改代码让客户端在主机坏的时候自动关闭连接?我可以在生成调度程序之前检查主机。但效率较低。

1 个答案:

答案 0 :(得分:0)

asyncore在简化错误处理方面没有提供太多帮助。大多数情况下,它让你对此负责。所以解决方案是在应用程序代码中添加错误处理:

try:
    client = HTTPClient('www.bocaonews.com.br', '/')
except socket.error as e:
    print 'Could not contact www.bocaonews.com.br:', e
else:
    asyncore.loop()

为了让您的生活更轻松,您可能不想在connect内拨打HTTPClient.__init__

另外,为了比较,这里是一个基于Twisted的HTTP / 1.1客户端:

from twisted.internet import reactor
from twisted.web.client import Agent

a = Agent(reactor)
getting = a.request(b"GET", b"http://www.bocaonews.com.br/")
def got(response):
    ...
def failed(reason):
    print 'Request failed:', reason.getErrorMessage()
getting.addCallbacks(got, failed)
reactor.run()