ホームページ バックエンド開発 Python チュートリアル Python の Asyncore 非同期ソケット モジュールとポート転送の例

Python の Asyncore 非同期ソケット モジュールとポート転送の例

Jun 16, 2016 am 08:47 AM

Asyncore モジュールは、ソケット サービスのクライアントとサーバーを非同期で作成するためのインフラストラクチャを提供します。

プログラムが単一のプロセッサ上で「同時に複数のことを実行する」には 2 つの方法しかありません。マルチスレッド プログラミングは最もシンプルで最も一般的な方法ですが、実際にマルチスレッドを使用せずにマルチスレッドのほぼすべての利点を維持できるようにする別の非常に異なる手法があります。 プログラムが主に I/O バウンドである場合、これが唯一の方法です。プログラムがプロセッサーに依存している場合、スレッドをプリエンプティブにスケジュールすることが本当に必要である可能性があります。ただし、プロセッサに依存する Web サーバーはほとんどありません。

オペレーティング システムが I/O ライブラリで select() システム コールをサポートしている場合 (ほぼすべてのシステムがサポートしています)、I/O が他の通信を行うときに、それを使用して複数の通信チャネルを同時に処理できます。バックグラウンドがビジー状態のときに作業します。この戦略は、特に最初は奇妙で複雑に見えるかもしれませんが、多くの点でマルチスレッド プログラミングよりも理解し、制御するのが簡単です。 asyncore モジュールは多くの問題を解決し、複雑で高性能なネットワーク サーバーとクライアントを迅速に構築できるようにします。会話型アプリケーションおよびプロトコルの場合、asynchat モジュールは非常に便利です。

これら 2 つのモジュールの背後にある考え方は、1 つ以上のネットワーク チャネルと、asyncore.dispatcher クラスと asynchat.async_chat クラスのインスタンスを作成することです。独自のマッピングを提供しない場合、チャネルの作成にはこれら 2 つが使用されます。インスタンスは、loop() 関数によって使用されるグローバル マップに追加されます。

最初のチャネルが作成されたら、loop() 関数を呼び出すとチャネル サービスがアクティブ化され、最後のチャネル (非同期サービスでマップに追加されたすべてのチャネルを含む) が閉じられるまで継続されます。
このモジュール ファイルには、loop() 関数とディスパッチャー基本クラスが含まれています。loop() 関数はグローバル関数であり、チャネルとも呼ばれるディスパッチャー インスタンスを保持する辞書をチェックします。
ディスパッチャ クラスを継承するすべてのオブジェクトは、処理が必要なソケットと見なすことができるため、これを使用する場合は、ディスパッチャを継承するクラスを定義し、いくつかのメソッド (通常は handle_ で始まるメソッド) を書き換えるだけで済みます。 。

ポート転送の例
プログラムが同時に 1 つのことを実行したい場合、マルチスレッドが最も速く最も一般的な方法ですが、別の方法もあります。この方法は次のとおりです。 I/O トラフィックが大きい場合に特に役立ちます。オペレーティング システムが選択機能をサポートしている場合は、バックグラウンドで I/O の読み取りおよび書き込みを行うことができます。このモジュールは複雑に思えますが、実際には理解する方法がたくさんあり、このドキュメントはそれらを解決するのに役立ちます。
このモジュールは、C++ のイベント選択モデルに似た、イベント駆動型の非同期 I/O であるべきだと思います。読み取りまたは書き込みイベントが発生するたびに、書き直したイベント関数によって処理されます。
asyncore モジュールを使用して書かれたポート転送スクリプトがあります。このスクリプトから、asyncore の基本的な使用法の概要を得ることができます。
この記事では、クライアントは私たちのコンピュータであり、サーバーは転送先のアドレスです。つまり、クライアントからこのスクリプトに送信された情報は、このスクリプトによってサーバーに転送されます。
まず、フォワーダー クラスを定義します。

class forwarder(asyncore.dispatcher):
  def __init__(self, ip, port, remoteip,remoteport,backlog=5):
    asyncore.dispatcher.__init__(self)
    self.remoteip=remoteip
    self.remoteport=remoteport
    self.create_socket(socket.AF_INET,socket.SOCK_STREAM)
    self.set_reuse_addr()
    self.bind((ip,port))
    self.listen(backlog)

  def handle_accept(self):
    conn, addr = self.accept()
    # print '--- Connect --- '
    sender(receiver(conn),self.remoteip,self.remoteport)
ログイン後にコピー

このクラスは、asyncore モジュールのディスパッチャー クラスを継承します (これは私たちのメインです)このクラスには、後でオーバーロードされるいくつかの関数が含まれています)、コンストラクターは 5 つのパラメーターを取得します。1 番目と 2 番目のパラメーターはスクリプトが監視するローカル IP とポート、3 番目と 4 番目のパラメーターはサーバーの IP とポートです。 5 番目のパラメータは listen 関数のパラメータで、待機キューの最大長です。
このクラスを使用するには、次のように新しいオブジェクトを作成し、対応する IP とポートを渡してループに入るだけです:

forwarder(options.local_ip,options.local_port,options.remote_ip,options.remote_port)
asyncore.loop()
ログイン後にコピー

ループに入った後は、バックグラウンドで実行されているデーモン スレッドを開始して、ソケット イベントが発生するのを待つのと同じです。
私たちのスクリプトはポート転送ツールであるため、実際に実行されるプロセスは次のとおりです。クライアントはこのスクリプトのポートに接続し、このポートに送信されたデータ スクリプトはサーバーのアドレスとポートに自動的に転送されます。したがって、最初に受信するのは接続メッセージ (accept イベント) である必要があります。
その後、accept イベントが発生すると、handle_accept 関数に入ります。したがって、handle_accept 関数が実際に accept 関数を呼び出して、クライアント接続オブジェクトとアドレスを受信することがわかります。取得後、新しい送信者クラス オブジェクトが作成されます。このオブジェクトは次のように定義されます。

这个类也是继承自asyncore.dispatcher,它的构造函数接收3个参数,分别是recv对象(这个之后说到),远端地址,对应端口。
函数中又新建了一个socket,这个socket就是和服务端端口通信的socket,然后调用connect连接这个端口。
之后其实也是进入了一个等待消息的过程,因为我们发送了一个connect,所以下一次接收到的消息应该是connect,而handle_connect是一个pass掉的函数。没有执行任何内容。
在连接完成后,我们就相当于建立好了一个端口转发的通道。当客户端向这个脚本监听的端口发送数据包时,它就会自动转发到服务端端口上。服务端端口返回的数据包,会自动转发到客户端上。
回到构造函数的第1个参数,我们在forwarder类函数中可以看到,传入的是一个receiver(conn)对象,receiver也是一个类,我们来看看这个类的定义:

class receiver(asyncore.dispatcher):
  def __init__(self,conn):
    asyncore.dispatcher.__init__(self,conn)
    self.from_remote_buffer=''
    self.to_remote_buffer=''
    self.sender=None

  def handle_connect(self):
    pass

  def handle_read(self):
    read = self.recv(4096)
    # print '%04i -->'%len(read)
    self.from_remote_buffer += read

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

  def handle_write(self):
    sent = self.send(self.to_remote_buffer)
    # print &#39;%04i <--&#39;%sent
    self.to_remote_buffer = self.to_remote_buffer[sent:]

  def handle_close(self):
    self.close()
    if self.sender:
      self.sender.close()
ログイン後にコピー

它也是继承了asyncore.dispatcher,构造函数只接收一个参数,就是connect的返回值,一个连接对象。
实际上这个对象它就是监听、处理与客户端的通信,而之前说的sender对象是监听、处理与服务端的通信。        

           

以上就是Python的Asyncore异步Socket模块及实现端口转发的例子的内容,更多相关内容请关注PHP中文网(www.php.cn)!


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPおよびPython:さまざまなパラダイムが説明されています PHPおよびPython:さまざまなパラダイムが説明されています Apr 18, 2025 am 12:26 AM

PHPは主に手順プログラミングですが、オブジェクト指向プログラミング(OOP)もサポートしています。 Pythonは、OOP、機能、手続き上のプログラミングなど、さまざまなパラダイムをサポートしています。 PHPはWeb開発に適しており、Pythonはデータ分析や機械学習などのさまざまなアプリケーションに適しています。

PHPとPythonの選択:ガイド PHPとPythonの選択:ガイド Apr 18, 2025 am 12:24 AM

PHPはWeb開発と迅速なプロトタイピングに適しており、Pythonはデータサイエンスと機械学習に適しています。 1.PHPは、単純な構文と迅速な開発に適した動的なWeb開発に使用されます。 2。Pythonには簡潔な構文があり、複数のフィールドに適しており、強力なライブラリエコシステムがあります。

PHPとPython:彼らの歴史を深く掘り下げます PHPとPython:彼らの歴史を深く掘り下げます Apr 18, 2025 am 12:25 AM

PHPは1994年に発信され、Rasmuslerdorfによって開発されました。もともとはウェブサイトの訪問者を追跡するために使用され、サーバー側のスクリプト言語に徐々に進化し、Web開発で広く使用されていました。 Pythonは、1980年代後半にGuidovan Rossumによって開発され、1991年に最初にリリースされました。コードの読みやすさとシンプルさを強調し、科学的コンピューティング、データ分析、その他の分野に適しています。

Python vs. JavaScript:学習曲線と使いやすさ Python vs. JavaScript:学習曲線と使いやすさ Apr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Sublime Code Pythonを実行する方法 Sublime Code Pythonを実行する方法 Apr 16, 2025 am 08:48 AM

PythonコードをSublimeテキストで実行するには、最初にPythonプラグインをインストールし、次に.pyファイルを作成してコードを書き込み、Ctrl Bを押してコードを実行する必要があります。コードを実行すると、出力がコンソールに表示されます。

vscodeでコードを書く場所 vscodeでコードを書く場所 Apr 15, 2025 pm 09:54 PM

Visual Studioコード(VSCODE)でコードを作成するのはシンプルで使いやすいです。 VSCODEをインストールし、プロジェクトの作成、言語の選択、ファイルの作成、コードの書き込み、保存して実行します。 VSCODEの利点には、クロスプラットフォーム、フリーおよびオープンソース、強力な機能、リッチエクステンション、軽量で高速が含まれます。

Visual StudioコードはPythonで使用できますか Visual StudioコードはPythonで使用できますか Apr 15, 2025 pm 08:18 PM

VSコードはPythonの書き込みに使用でき、Pythonアプリケーションを開発するための理想的なツールになる多くの機能を提供できます。ユーザーは以下を可能にします。Python拡張機能をインストールして、コードの完了、構文の強調表示、デバッグなどの関数を取得できます。デバッガーを使用して、コードを段階的に追跡し、エラーを見つけて修正します。バージョンコントロールのためにGitを統合します。コードフォーマットツールを使用して、コードの一貫性を維持します。糸くずツールを使用して、事前に潜在的な問題を発見します。

メモ帳でPythonを実行する方法 メモ帳でPythonを実行する方法 Apr 16, 2025 pm 07:33 PM

メモ帳でPythonコードを実行するには、Python実行可能ファイルとNPPEXECプラグインをインストールする必要があります。 Pythonをインストールしてパスを追加した後、nppexecプラグインでコマンド「python」とパラメーター "{current_directory} {file_name}"を構成して、メモ帳のショートカットキー「F6」を介してPythonコードを実行します。

See all articles