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 に答える