0

ポート 8080 で実行されるねじれた python サーバーがあり、このサーバーで実行されるさまざまな API を作成しました。したがって、これらすべての API を単一のポート番号で実行したいと考えています。しかし、同じポートを使用しようとすると、ex : 8081 のすべての API が使用され、Python インタープリターを使用して同時に実行されます。その時点で、次のエラーが表示されます: twisted.internet.error.CannotListenError: Couldn't listen on any:8081: [Errno 98] アドレスは既に使用されています。私はツイストに慣れていないので、多くのことを知りません。また、ツイストに関する適切なドキュメントもありません。誰かがこのエラーを解決するために私を案内してください:

コードスニペットは次のとおりです。

from twisted.internet import epollreactor

epollreactor.install()

from zope.interface import implements
from twisted.internet import reactor,interfaces
from functools import partial
from pymongo import Connection
import json
from bson.objectid import ObjectId
import server_1
import replacePlus_Space

global data, data_new, datadB, coll_auth, coll_person


class Login_user(server_1.HTTPEchoFactory):

    def __init__(self):
        server_1.HTTPEchoFactory.__init__(self,"testsite")
        server_1.HTTPEchoFactory.initResources(self)
        self.initResources()

    def initResources(self):
        print "in Login"
        self.responses["/login_user"] = partial(self.user_login)


    # To connect to DB and Check error cases and insert into mongoDB..!!!
    def user_login(self, client):
        # some functinality..!!!!

d = Login_user()

reactor.listenTCP(8081,d)

reactor.run()         

2 番目のコード スニペットは次のとおりです。

from twisted.internet import epollreactor

epollreactor.install()

from zope.interface import implements
from twisted.internet import reactor,interfaces
from functools import partial
from pymongo import Connection
import json
from bson.objectid import ObjectId
import server_1
import replacePlus_Space

class AddFriendDB(server_1.HTTPEchoFactory):

    def __init__(self):
        server_1.HTTPEchoFactory.__init__(self,"testsite")
        server_1.HTTPEchoFactory.initResources(self)
        self.initResources()

    def initResources(self):
        print "in add friend"
        self.responses["/addFriend_DB"] = partial(self.addFriendDB)


    # To connect to DB and Check error cases and insert into mongoDB..!!!
    def addFriendDB(self, client):
        #some functionality here..!!!

d = AddFriendDB()

reactor.listenTCP(8081,d)

reactor.run()
4

2 に答える 2

8

質問の翻訳

あなたの質問の詳細の多くは意味をなさないので、私はあなたの質問を次のように翻訳しています:

ポート 8080 で実行されるツイスト pythonスタンドアロン プログラムがあり、このサーバーで実行される別のスタンドアロン プログラムを作成しました。両方のプログラムを単一のポート番号で実行したい。すべてのプログラムに同じポートを使用しようとすると例:両方のプログラムにポート8081を使用します。次のエラーが表示されます: 。はツイストに慣れていないので、多くのことを知りません。また、ツイストに関する適切なドキュメントもありません。誰かがこのエラーを解決するために私を案内してください。twisted.internet.error.CannotListenError: Couldn't listen on any:8081: [Errno 98] Address already in use

Twisted には優れたドキュメントがあります

あなたは次のようにコメントしました:

[...] ツイストに関する適切なドキュメントはありません

その発言はあからさまに間違っています。

Twisted には確かに適切なドキュメントがあり、ほとんどのフレームワークと比較して優れたドキュメントがあります。多くの高品質のドキュメント ソースのほんの一部を挙げると、次のようになります。

  1. Dave Peticola (krondo) のTwisted Introduction - Twisted が構築されているテクノロジの説明から始まる、Twisted の優れた深い紹介です。ねじれを本当に理解したい場合は、この (長い) 紹介が出発点です
  2. Twisted の主要な Web サイトtwistedmatrix.comの高品質で豊富なドキュメント
  3. ソースそのもの。上記のドキュメンテーションがコードから何を理解する必要があるかを教えていない場合、Twisted はよくコメントしており、驚くほどソースを理解しています。

「アドレスは既に使用されています」の原因

Bart Friederichsが以前に回答したように:

特定のポートでリッスンできるプロセスは 1 つだけです。ポート 8081 でリッスンするプロセス 1 を開始し、同じポートで別のプロセスを開始すると、このエラーが発生します。

これは、python や twisted からではなく、TCP スタックからのエラーです。

これは、すべてのオペレーティング システム (または、少なくとも Python を実行できるすべてのプロセス ベースのオペレーティング システム) にわたる TCP/IP スタックの基本的な真実です。

エラーは、OS/IP スタックが 1 つのプロセス (そのポートでアプリケーション レベルのプロトコルを実装しているプロセス) にのみ転送するように設計されていることを、オペレーティング システムが思い出させることです。このエラーは、他のプログラムがすでに登録しているポートを 2 番目のプログラムが再登録しようとしたときに発生します。

一般的な回避策

このようなポートの再利用の問題が発生した場合は、自問する必要があります。

  1. 2 つのプログラムは、同じアプリケーション レベルのプロトコルを実行していますか?
  2. それらが同じプロトコルである場合、プロトコルには、特定のトランザクションに対して正しいサブプログラム/ルーチンが識別されるようなルーティングがありますか?
  3. 2 つのプログラムはルーティング内の別の場所にありますか?

それらが同じプロトコルではない場合 (IE 1 が HTTP で、もう 1 つは FTP)、または同じプロトコルであるが、ルーティングを持たないプロトコル (IE 2 つの NTP インスタンス) である場合、混合する簡単な方法はありません。 IP の法則 (およびアプリケーション プロトコルの実装の構築方法) を破ろうとしているからです。唯一の解決策は、プロトコルの 1 つ (または両方) を、アプリケーション レベルのルーティングも行う共通のプロトコルにカプセル化することです (IE は HTTP 内に FTP をカプセル化し、URI を使用してルーティングします)。

それらが同じプロトコルであり、プロトコルがトランザクションごとのルーティング (つまり、HTTP トランザクション内の URI) を提供し、それらが同じルーティング場所にない場合、より簡単な解決策があります。

  1. 2 つのアプリケーションを 1 つにマージします。

    それらが同じルーティング可能なプロトコルであるが、別の場所にある場合 (最初のプログラムの URI/loginと の 2 番目のプログラムの URI を持つ IE HTTP プロトコル/addfriend)、2 つのプログラム/プロセスのルーティング後のロジックを取り出してそれらをマージするのは簡単です。両方の機能を実行する 1 つのプログラムに

  2. プログラムをリダイレクタでフロントエンドします (このソリューションは、利用可能なツールがあるため、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/foofoo ページを指定すると、表示されます。

#!/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()
于 2014-06-04T16:05:31.967 に答える
3

特定のポートでリッスンできるプロセスは 1 つだけです。ポート 8081 でリッスンするプロセス 1 を開始し、同じポートで別のプロセスを開始すると、このエラーが発生します。

これは、python や twisted からではなく、TCP スタックからのエラーです。

プロセスごとに異なるポートを選択するか、分岐サーバーを作成して修正してください。

于 2014-06-04T11:58:16.067 に答える