有没有办法限制 Twisted 协议服务器中特定端口的连接数?

Is there a way to restrict number of connections to a specific port in a Twisted protocol server?

我有一个 python Twisted 服务器应用程序与遗留客户端应用程序接口,每个客户端都分配了一个特定端口以连接到服务器。所以我已经在服务器上的所有这些端口上设置了监听器并且它工作得很好,但我需要建立一些安全措施来禁止多个客户端连接到同一服务器端口。当另一个客户端连接到同一端口时,客户端应用程序上有太多东西会中断,我现在无法更新该应用程序。我必须忍受它的运作方式。 我知道我可以在 connectionMade() 函数中构建一些逻辑来查看是否有人已经存在于该端口上,如果已经存在,则关闭这个新连接。但我宁愿有一种方法可以拒绝它,所以甚至不允许客户端连接。然后客户端就会知道他们犯了错误,他们可以更改他们尝试连接的端口。

如果有帮助,这是我的服务器代码的精简版本。

from twisted.internet.protocol import Factory
from twisted.internet.protocol import Protocol
from twisted.internet import reactor
from twisted.internet import task
import time

class MyServerTasks():
    def someFunction(msg):
        #Do stuff

    def someOtherFunction(msg):
        #Do other stuff

class MyServer(Protocol):

    def __init__(self, users):
        self.users = users
        self.name = None

    def connectionMade(self):
        #Depending on which port is connected, go do stuff

    def connectionLost(self, reason):
        #Update dictionaries and other global info

    def dataReceived(self, line):
        t = time.strftime('%Y-%m-%d %H:%M:%S')
        d = self.transport.getHost()
        print("{} Received message from {}:{}...{}".format(t, d.host, d.port, line))  #debug
        self.handle_GOTDATA(line)

    def handle_GOTDATA(self, msg):
        #Parse the received data string and do stuff based on the message.
        #For example:
        if "99" in msg:
            MyServerTasks.someFunction(msg)

class MyServerFactory(Factory):

    def __init__(self):
        self.users = {} # maps user names to Chat instances

    def buildProtocol(self, *args, **kwargs):
        protocol = MyServer(self.users)
        protocol.factory = self
        protocol.factory.clients = []
        return protocol

reactor.listenTCP(50010, MyServerFactory())
reactor.listenTCP(50011, MyServerFactory())
reactor.listenTCP(50012, MyServerFactory())
reactor.listenTCP(50013, MyServerFactory())

reactor.run()

当客户端连接到服务器时,twisted使用factory创建 protocol(通过调用其 buildProtocol 方法)实例来处理客户端请求。

因此您可以在 MyServerFactory 中维护已连接客户端的计数器, 如果计数器已达到最大允许连接客户端,您可以 return None 而不是为该客户端创建新协议。 如果工厂没有 return 来自的协议,Twisted 将关闭客户端连接 它的 buildProtocol 方法。

you can see here

class MyServer(Protocol):

def __init__(self, users):
    self.users = users
    self.name = None

def connectionMade(self):
    #Depending on which port is connected, go do stuff

def connectionLost(self, reason):
    #Update dictionaries and other global info
    self.factory.counter -= 1

def dataReceived(self, line):
    t = time.strftime('%Y-%m-%d %H:%M:%S')
    d = self.transport.getHost()
    print("{} Received message from {}:{}...{}".format(t, d.host, d.port, line))  #debug
    self.handle_GOTDATA(line)

def handle_GOTDATA(self, msg):
    #Parse the received data string and do stuff based on the message.
    #For example:
    if "99" in msg:
        MyServerTasks.someFunction(msg)



 class MyServerFactory(Factory):
   MAX_CLIENT = 2

 def __init__(self):
    self.users = {} # maps user names to Chat instances
    self.counter = 0

 def buildProtocol(self, *args, **kwargs):
    if self.counter == self.MAX_CLIENT:
        return None
    self.counter += 1
    protocol = MyServer(self.users)
    protocol.factory = self
    protocol.factory.clients = []
    return protocol