我有一个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
如果计数器已经达到允许连接的最大客户端,你可以返回到一个新的客户端。None
而不是为该客户端创建新的协议。buildProtocol
方法。
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