如何解决twisted.internet.error.CannotListenError:无法侦听任何:8081:[Errno 98]地址已被使用

G-C*_*der 0 html python twisted.internet

我有一个在端口8080上运行的扭曲的python服务器,我已经编写了在这个服务器上运行的不同的API.所以我希望所有这些API都在单个端口上运行.但当我尝试使用相同的端口所有API的ex:8081并使用python解释器同时运行.那时我收到这个错误:twisted.internet.error.CannotListenError:无法侦听任何: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()         
Run Code Online (Sandbox Code Playgroud)

第二个代码段是:

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()
Run Code Online (Sandbox Code Playgroud)

Mik*_*utz 6

翻译问题

你问题中的许多细节都没有意义,所以我将你的问题翻译成:

我有一个扭曲的蟒蛇独立程序运行在端口8080,我已经写了一个不同的独立的程序,它运行在此服务器上.我希望两个程序都在单个端口上运行.当我尝试为所有程序使用相同的端口时:使用端口 8081 进行两个程序.我收到这个错误:twisted.internet.error.CannotListenError: Couldn't listen on any:8081: [Errno 98] Address already in use.由于我是新来的扭曲,我不知道很多事情,并没有关于扭曲的适当文件.请有人指导我解决这个错误.

Twisted有很棒的文档

你评论说:

[...]没有关于扭曲的适当文件

该声明显然是错误的.

Twisted肯定有适当的文档,与大多数框架相比,它有很好的文档.仅举几个高质量的文档资料来源:

  1. Dave Peticola(krondo)扭曲介绍 - 对扭曲的优秀而深入的介绍,首先是解释Twisted的技术.如果你真的想要了解扭曲,这个(长期)介绍是开始的地方
  2. 关于Twisted主要网站twistedmatrix.com的高质量和广泛的文档
  3. 该源本身.如果上面的文档没有教你如何从代码中找出它,那么Twisted有很好的评论和令人惊讶的理解源.

导致"地址已在使用"的原因

正如Bart Friederichs 先前的回答:

只有一个进程可以侦听某个端口.如果您启动进程1以侦听端口8081,然后在同一端口上启动另一个进程,则会出现此错误.

这是来自TCP堆栈的错误,而不是来自python或twisted.

这是所有操作系统(或至少所有可运行Python的基于进程的操作系统)的TCP/IP堆栈的基本事实.

错误是您的操作系统提醒您,当数据到达IP端口时,OS/IP堆栈被设计为仅转发到一个进程,该进程正在该端口上实现应用程序级协议.当第二个程序尝试重新注册其他程序已经注册的端口时,会发生错误.

一般的解决方法

遇到像这样的端口重用问题,你必须问自己:

  1. 这两个程序是否运行相同的应用程序级协议?
  2. 如果它们是相同的协议,协议是否具有路由,以便对于任何给定的事务,识别正确的子程序/例程?
  3. 这两个程序是否位于路由中的不同位置?

如果它们不是相同的协议(IE一个是HTTP而另一个是FTP)或者它们是相同的协议但是它的协议没有路由(IE的两个NTP实例)那么就没有简单的方法来混合它们是因为您试图违反IP法则(以及构建应用程序协议实现的方式).唯一的解决方案是将一个(或两个)协议封装到一个通用协议中,该协议也具有应用级路由(IE封装FTP内部的HTTP并使用URI路由)

如果它们是相同的协议,并且协议提供了每事务路由(IE是HTTP事务中的URI)并且它们不在同一路由位置,那么有更简单的解决方案,即:

  1. 将两个应用程序合并为一个.

    如果它们是相同的可路由协议但是在不同的位置(IE HTTP协议具有第一个程序的URI /login和第二个程序/addfriend),那么拉出两个程序/进程的路由后逻辑并合并它们应该是微不足道的.进入一个兼具两种功能的程序

  2. 使用重定向器前端程序(由于可用的工具,此解决方案只能通过HTTP轻松实现).

    如果你有HTTP协议程序有路由到不同的位置,但由于某种原因很难将逻辑合并在一起(IE一个程序用Java编写,另一个用Python编写)然后你可以看看前端两个程序像nginx这样的重定向器

    在这种情况下使用重定向器的方法是在两个不同的未使用端口(IE 12001,12002)上运行您的两个应用程序,然后在您希望服务所在的端口上运行重定向器,并使用配置文件将通过其唯一的路由位置重定向到您的两个程序(通过SF等配置:如何使用nginx将请求重定向到其他域/ URL)

代码示例

以下三个程序说明了将两个程序合并为一个程序的过程,因此可以从同一个端口访问这两组逻辑.

两个独立的计划:

如果运行以下代码,将启动Web服务器localhost:8081.然后,如果您将Web浏览器指向http://127.0.0.1:8081/blahblah页面,则会显示.

#!/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()
Run Code Online (Sandbox Code Playgroud)

此代码将启动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()
Run Code Online (Sandbox Code Playgroud)

合并逻辑

此代码是前两个程序的合并,因为您可以看到它只需要复制少量代码以将上述两个代码粘合到一个允许访问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()
Run Code Online (Sandbox Code Playgroud)