この記事では、Python の asyncore モジュールの原理と使用法を例とともに分析し、参考のために皆さんと共有します。具体的な分析は次のとおりです。
asyncore ライブラリは Python の標準ライブラリであり、非同期ソケットのラッパーです。ネットワークを操作するとき、ソケットなどの基盤となるライブラリを直接使用できますが、asyncore を使用すると、ネットワークをより便利に操作でき、ソケット、選択、ポーリングなどのツールを直接使用するときに直面する必要がある複雑さを回避できます。
このライブラリは関数とクラスを含む非常にシンプルです
*loop() 関数
* ディスパッチャー基本クラス
ループ関数はグローバルであり、ディスパッチャ メソッドではないことに注意してください
ディスパッチャーから継承されたクラスのすべてのオブジェクトは、処理する必要があるソケットとみなすことができます。これには、TCP 接続や UDP、あるいはその他の一般的ではない接続も含まれます。使い方は簡単です。ディスパッチャを継承するクラスを定義するだけで、いくつかのメソッドをオーバーライドできます。
書き直す必要があるメソッドは通常、handle_ で始まります。
class refuse(dispatcher): def handle_accept(): #do nothing ... pass
loop() 関数は、ディスパッチャ インスタンスを格納する辞書を検出する役割を果たします。この辞書はチャネルと呼ばれます。ディスパッチャ オブジェクトが作成されるたびに、デフォルトの dict に追加されます (もちろん、チャネルを自分で指定することもできます)。オブジェクトがチャネルに追加されると、ソケットの動作が定義され、プログラムはloop()を呼び出すだけですべての機能が実現されます。
asyncore は Python 標準ライブラリの優れた設計です
Python の標準ドキュメントには、asyncore
import asyncore, socket class http_client(asyncore.dispatcher): def __init__(self, host, path): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.connect( (host, 80) ) self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path 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:] c = http_client('www.python.org', '/') asyncore.loop()
この関数を実行すると、python.org のホームページがダウンロードされたことがわかります。つまり、http 層プロトコルが実装されているということです。しかし、私たちが使用しているのはソケット レベルの API だけです...それでは、これらのコード行の謎を見てみましょう!
writable と readable は、ソケットが書き込めるかデータが到着したことを検出したときに呼び出され、handle_read か handle_write かを決定するブール値を返します
asyncore.py を開くと、ディスパッチャー クラスで定義された書き込み可能および読み取り可能なメソッドの定義が非常に単純であることがわかります。
def readable(self): return True def writable(self): return True
つまり、読み取り可能または書き込み可能であることが検出されると、handle_read/handle_write が直接呼び出されますが、上記の例では、オーバーロードが表示されます (C++ の仮想関数のように見えますね。 )
def writable(self): return (len(self.buffer) > 0)
明らかに、送信するデータがある場合は、writable の呼び出し元に True を返すだけなので、handle_write でそれ以上の判断を行う必要はありません。ロジックもコードも明確で、唯一のフライインです。軟膏は理解するのに少し時間がかかりますが、難しいことではありません。
コードの残りの部分は非常に明瞭に見え、兵士がそれを阻止しに来ているように感じられます。 http サーバーがリクエストを完了してソケットを閉じると、 それに応じて handle_close() もそのミッションを完了します。 close() はオブジェクト自体をチャネルから削除し、ソケット オブジェクトを破棄します。
def close(self): self.del_channel() self.socket.close()
loop() 関数は空のチャンネルを検出し、ループを終了します。プログラムはタスクを完了して終了します。
この記事が皆さんの Python プログラミング設計に役立つことを願っています。