0
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,因此引发了错误。

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

4

1 回答 1

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()
于 2013-11-13T12:45:52.667 回答