从 Python 中的一个类创建多个 tcp 套接字处理程序

问题描述

是否可以在 python3 中创建一个可以有多个唯一实例的 TCP Socket 处理程序类?

我有 2 个线程 TCP 套接字服务器,它们为连接的客户端提供唯一信息。我正在尝试使“节点 1”套接字服务器处理程序仅提供“节点 1”的数据,而“节点 2”套接字服务器处理程序将提供“节点 2”的数据。

我使用变量“node”制作了一个自定义处理程序。

class NodeTCPHandler(socketserver.BaseRequestHandler):

    def __init__(self,request,client_address,server):
        socketserver.BaseRequestHandler.__init__(self,server)
        self.node = 6
        return
    
    def handle(self):
        logging.debug("Node Socket has been started")
        global stop,temperature,humidity,pressure,voltage
        
        logging.debug("{} connected to Node 0{} Socket".format(self.client_address[0],self.node+1))
        
        while not stop:
            msg = (str(temperature[self.node])+','+str(humidity[self.node])+','+str(pressure[self.node])+','+str(voltage[self.node]))
            self.request.sendall(msg.encode())
            time.sleep(5)

我尝试在创建套接字服务器并定义处理程序后设置变量“节点”。

node_01_server = socketserver.Tcpserver((hostAddr,nodePort[0]),NodeTCPHandler)
node_01_server.RequestHandlerClass.node = 0
node_02_server = socketserver.Tcpserver((hostAddr,nodePort[1]),NodeTCPHandler)
node_02_server.RequestHandlerClass.node = 1

node_01_thread = threading.Thread(name='Node 01 Socket',target=node_01_server.serve_forever)
node_02_thread = threading.Thread(name='Node 02 Socket',target=node_02_server.serve_forever)

这接近工作,但是当我设置“node_02_server.RequestHandlerClass.node”时,它也会覆盖“node_01_server.RequestHandlerClass.node”节点变量!

我显然遗漏了一些东西,但我觉得我已经接近解决方案了。这是我第一次真正尝试使用类和套接字服务器,所以如果我犯了任何明显的错误,请告诉我。

解决方法

node_01_server.RequestHandlerClass.node = 0 设置类属性 RequestHandlerClass.node,而不是您似乎想要更改的实例属性。并且由于类 node 只能有一个类属性 RequestHandlerClass,因此在每一行上都会更新。

让我们考虑几种分离处理程序的方法:

  1. 实现几个NodeTCPHandler并将正确的一个传递给TCPServer

    class BaseNodeTCPHandler(socketserver.BaseRequestHandler):
        NODE_TYPE = 6
    
        def __init__(self,*args,**kwargs):
            self.node = self.NODE_TYPE
            super().__init__(*args,**kwargs)
    
    class Node0TCPHandler(BaseNodeTCPHandler):
        NODE_TYPE = 0
    
    class Node1TCPHandler(BaseNodeTCPHandler):
        NODE_TYPE = 1
    

    现在您可以将这些 Node0TCPHandler/Node1TCPHandler 传递到适当的服务器

    node_01_server = socketserver.TCPServer((hostAddr,nodePort[0]),Node0TCPHandler)
    node_02_server = socketserver.TCPServer((hostAddr,nodePort[1]),Node1TCPHandler)
    
  2. 实现自定义 TCPServer,它可以接受额外的参数并将它们传递给处理程序的构造函数

    class NodeTCPHandler(socketserver.BaseRequestHandler):
    
        def __init__(self,node,**kwargs):
            self.node = node
            super().__init__(*args,**kwargs)
    
    class CustomTCPServer(socketserver.TCPServer):
    
        def __init__(self,node=6,**kwargs):
            super().__init__(*args,**kwargs)
            self.node = node
    
        def finish_request(self,request,client_address):
            """Finish one request by instantiating RequestHandlerClass."""
            self.RequestHandlerClass(self.node,client_address,self)
    
    

    现在您可以使用不同的 node 值来实例化服务器:

    node_01_server = CustomTCPServer((hostAddr,NodeTCPHandler,node=0)
    node_02_server = CustomTCPServer((hostAddr,node=1)
    

第一种方法更好,因为它需要在较少数量的类中进行修复,尤其是在有更多类似更新时。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...