質問の翻訳
あなたの質問の詳細の多くは意味をなさないので、私はあなたの質問を次のように翻訳しています:
ポート 8080 で実行されるツイスト pythonスタンドアロン プログラムがあり、このサーバーで実行される別のスタンドアロン プログラムを作成しました。両方のプログラムを単一のポート番号で実行したい。すべてのプログラムに同じポートを使用しようとすると、例:両方のプログラムにポート8081を使用します。次のエラーが表示されます: 。私はツイストに慣れていないので、多くのことを知りません。また、ツイストに関する適切なドキュメントもありません。誰かがこのエラーを解決するために私を案内してください。twisted.internet.error.CannotListenError: Couldn't listen on any:8081: [Errno 98] Address already in use
Twisted には優れたドキュメントがあります
あなたは次のようにコメントしました:
[...] ツイストに関する適切なドキュメントはありません
その発言はあからさまに間違っています。
Twisted には確かに適切なドキュメントがあり、ほとんどのフレームワークと比較して優れたドキュメントがあります。多くの高品質のドキュメント ソースのほんの一部を挙げると、次のようになります。
- Dave Peticola (krondo) のTwisted Introduction - Twisted が構築されているテクノロジの説明から始まる、Twisted の優れた深い紹介です。ねじれを本当に理解したい場合は、この (長い) 紹介が出発点です
- Twisted の主要な Web サイトtwistedmatrix.comの高品質で豊富なドキュメント
- ソースそのもの。上記のドキュメンテーションがコードから何を理解する必要があるかを教えていない場合、Twisted はよくコメントしており、驚くほどソースを理解しています。
「アドレスは既に使用されています」の原因
Bart Friederichsが以前に回答したように:
特定のポートでリッスンできるプロセスは 1 つだけです。ポート 8081 でリッスンするプロセス 1 を開始し、同じポートで別のプロセスを開始すると、このエラーが発生します。
これは、python や twisted からではなく、TCP スタックからのエラーです。
これは、すべてのオペレーティング システム (または、少なくとも Python を実行できるすべてのプロセス ベースのオペレーティング システム) にわたる TCP/IP スタックの基本的な真実です。
エラーは、OS/IP スタックが 1 つのプロセス (そのポートでアプリケーション レベルのプロトコルを実装しているプロセス) にのみ転送するように設計されていることを、オペレーティング システムが思い出させることです。このエラーは、他のプログラムがすでに登録しているポートを 2 番目のプログラムが再登録しようとしたときに発生します。
一般的な回避策
このようなポートの再利用の問題が発生した場合は、自問する必要があります。
- 2 つのプログラムは、同じアプリケーション レベルのプロトコルを実行していますか?
- それらが同じプロトコルである場合、プロトコルには、特定のトランザクションに対して正しいサブプログラム/ルーチンが識別されるようなルーティングがありますか?
- 2 つのプログラムはルーティング内の別の場所にありますか?
それらが同じプロトコルではない場合 (IE 1 が HTTP で、もう 1 つは FTP)、または同じプロトコルであるが、ルーティングを持たないプロトコル (IE 2 つの NTP インスタンス) である場合、混合する簡単な方法はありません。 IP の法則 (およびアプリケーション プロトコルの実装の構築方法) を破ろうとしているからです。唯一の解決策は、プロトコルの 1 つ (または両方) を、アプリケーション レベルのルーティングも行う共通のプロトコルにカプセル化することです (IE は HTTP 内に FTP をカプセル化し、URI を使用してルーティングします)。
それらが同じプロトコルであり、プロトコルがトランザクションごとのルーティング (つまり、HTTP トランザクション内の URI) を提供し、それらが同じルーティング場所にない場合、より簡単な解決策があります。
2 つのアプリケーションを 1 つにマージします。
それらが同じルーティング可能なプロトコルであるが、別の場所にある場合 (最初のプログラムの URI/login
と の 2 番目のプログラムの URI を持つ IE HTTP プロトコル/addfriend
)、2 つのプログラム/プロセスのルーティング後のロジックを取り出してそれらをマージするのは簡単です。両方の機能を実行する 1 つのプログラムに
プログラムをリダイレクタでフロントエンドします (このソリューションは、利用可能なツールがあるため、HTTP でのみ簡単です)。
別の場所にルーティングする HTTP プロトコル プログラムがあるが、何らかの理由でロジックをマージするのが難しい場合 (つまり、1 つのプログラムが Java で記述され、もう 1 つのプログラムが Python で記述されている)、両方のプログラムのフロントエンドをnginxのようなリダイレクタ
このような場合にリダイレクタを使用する方法は、2 つの異なる未使用ポート (IE 12001、12002) で 2 つのアプリを実行してから、サービスをオンにしたいポートでリダイレクタを実行することです。一意のルーティング場所を介して 2 つのプログラムにリダイレクトする構成ファイル (SF のような構成を介して: How to redirect requests to a different domain/url with nginx )
コード例
次の 3 つのプログラムは、2 つのプログラムを 1 つにマージするプロセスを示しているため、両方のロジック セットに同じポートからアクセスできます。
2 つの別個のプログラム:
次のコードを実行すると、Web サーバーが で起動されlocalhost:8081
ます。次に、Web ブラウザーをhttp://127.0.0.1:8081/blah
何とかページに向けると、表示されます。
#!/usr/bin/python
from twisted.internet import defer, protocol, reactor # the reactor
from twisted.web.server import Site # make the webserver go
from twisted.web.resource import Resource
class BlahPage(Resource):
idLeaf = True
def render_GET(self, request):
return "<html><body>Blah Page!</body></html>"
class ShutdownPage(Resource):
def render_GET(self, request):
reactor.stop()
webroot = Resource()
webroot.putChild("blah", BlahPage())
webroot.putChild("shutdown", ShutdownPage())
def main():
# Register the webserver (TCP server) into twisted
webfactory = Site(webroot)
reactor.listenTCP(8081, webfactory)
print ("Starting server")
reactor.run()
if __name__ == '__main__':
main()
このコードは で Web サーバーを起動しますlocalhost:8082
。その後、Web ブラウザでhttp://127.0.0.1:8082/foo
foo ページを指定すると、表示されます。
#!/usr/bin/python
from twisted.internet import defer, protocol, reactor # the reactor
from twisted.web.server import Site # make the webserver go
from twisted.web.resource import Resource
class FooPage(Resource):
idLeaf = True
def render_GET(self, request):
return "<html><body>Foo Page!</body></html>"
class ShutdownPage(Resource):
def render_GET(self, request):
reactor.stop()
webroot = Resource()
webroot.putChild("foo", FooPage())
webroot.putChild("shutdown", ShutdownPage())
def main():
# Register the webserver (TCP server) into twisted
webfactory = Site(webroot)
reactor.listenTCP(8082, webfactory)
print ("Starting server")
reactor.run()
if __name__ == '__main__':
main()
ロジックのマージ
このコードは、前の 2 つのプログラムをマージしたものです。少量のコードをコピーして、上記の両方を と へのアクセスを可能にする 1 つに結合するだけで済みhttp://127.0.0.1:8080/blah
ますhttp://127.0.0.1:8080/blah
。
#!/usr/bin/python
from twisted.internet import defer, protocol, reactor # the reactor
from twisted.web.server import Site # make the webserver go
from twisted.web.resource import Resource
class BlahPage(Resource):
idLeaf = True
def render_GET(self, request):
return "<html><body>Blah Page!</body></html>"
class FooPage(Resource):
idLeaf = True
def render_GET(self, request):
return "<html><body>Foo Page!</body></html>"
class ShutdownPage(Resource):
def render_GET(self, request):
reactor.stop()
webroot = Resource()
webroot.putChild("foo", FooPage())
webroot.putChild("blah", BlahPage())
webroot.putChild("shutdown", ShutdownPage())
def main():
# Register the webserver (TCP server) into twisted
webfactory = Site(webroot)
reactor.listenTCP(8080, webfactory)
print ("Starting server")
reactor.run()
if __name__ == '__main__':
main()