python - 如何将对象实例传递给 SocketServer.BaseRequestHandler 实例?

标签 python python-2.7 sockets tcp socketserver

这是个问题。 我的主要工作是:将“s”对象传递给 TestRequestHandler 类中的“handle”方法。 我的第一步是:通过“point”方法将“s”对象传递给 TestServer 类,但我在这里卡住了。如何将“s”对象传递给TestRequestHandler?有什么建议吗?

import threading
import SocketServer
from socket import *

class TestRequestHandler(SocketServer.BaseRequestHandler):

    def __init__(self, request, client_address, server):
        SocketServer.BaseRequestHandler.__init__(self, request, client_address, server)
        return

    def setup(self):
        return SocketServer.BaseRequestHandler.setup(self)

    def handle(self):
        data = self.request.recv(1024)

        if (data): 
            self.request.send(data)
            print data

    def finish(self):
        return SocketServer.BaseRequestHandler.finish(self)

class TestServer(SocketServer.TCPServer):

    def __init__(self, server_address, handler_class=TestRequestHandler):
        print "__init__"
        SocketServer.TCPServer.__init__(self, server_address, handler_class)
        return

    def point(self,obj):
        self.obj = obj
        print "point"

    def server_activate(self):
        SocketServer.TCPServer.server_activate(self)
        return

    def serve_forever(self):
        print "serve_forever"
        while True:
            self.handle_request()
        return

    def handle_request(self):
        return SocketServer.TCPServer.handle_request(self)

if __name__ == '__main__':

    s = socket(AF_INET, SOCK_STREAM)

    address = ('localhost', 6666)
    server = TestServer(address, TestRequestHandler)
    server.point(s)
    t = threading.Thread(target=server.serve_forever())
    t.setDaemon(True)
    t.start()

最佳答案

如果我理解正确,我认为您可能误解了该模块的工作原理。您已经指定了要绑定(bind)的服务器的地址“localhost:6666”。

当您通过调用serve_forever()启动服务器时,这将导致服务器开始监听 localhost:6666 上的套接字。

根据文档,该套接字作为“请求”对象传递给您的 RequestHandler。当套接字上接收到数据时,您的“处理”方法应该能够使用记录的套接字 API 从该对象接收/发送到该对象。

如果您想要进一步抽象,看起来您的 RequestHandler 可以从 StreamRequestHandler 扩展并使用类似文件的对象读取/写入套接字。

重点是,您无需创建额外的套接字,然后尝试强制服务器使用新的套接字。 SocketServer 模块的部分值(value)在于它为您管理套接字的生命周期。

另一方面,如果您想从客户端的角度测试服务器,那么您需要创建一个可以读取/写入客户端请求的套接字。但您本身永远不会将此套接字传递给您的服务器。您可能会在一个完全独立的进程中执行此操作,并通过套接字上的 IPC 测试您的服务器。

根据新信息进行编辑

要让服务器 A 在服务器 A 接收数据时打开到服务器 B 的套接字,一种解决方案是简单地从 RequestHandler 内部打开一个套接字。也就是说,您可能需要根据服务要求解决一些其他设计问题。

例如,您可能想要使用一个简单的连接池,该连接池打开一些到服务器 B 的套接字,服务器 A 可以像资源一样使用这些套接字。 Python 中可能已经有一些库可以帮助解决这个问题。

鉴于您当前的设计,您的 RequestHandler 可以作为成员变量访问服务器,因此您可以执行以下操作:

class TestServer(SocketServer.TCPServer):
     def point (self, socketB):
         self.socketB = socketB # hold serverB socket

class TestRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        data = self.request.recv(1024)

        if (data): 
            self.request.send(data)
            print data

        self.server.socketB ... # Do whatever with the socketB

但就像我说的,最好有某种连接池或其他对象来管理服务器 B 套接字,以便服务器 A 处理程序可以在处理传入请求时获取/释放套接字。

这样你就可以更好地处理服务器 B 中断套接字的情况。您当前的设计无法轻松处理损坏的套接字。只是一些想法...

关于python - 如何将对象实例传递给 SocketServer.BaseRequestHandler 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/711002/

相关文章:

python - 检查 DataFrame 中的哪些列是分类的

python - 将复数的 Pandas 数据框导出到excel

python - 如何添加两个嵌套的Python字典?

python - 识别列表中的不同元素并将其映射到 python 中另一个列表中的相应索引

Java 信使套接字

Python 列表理解

c++ - 在 c++ boost python 列表中附加整数时出错

python - 如何将日期格式作为参数传递给 Mysqldb 执行方法

c - 套接字: "fd"和 "select"操作的任何库或包装器?

java套接字与服务器端断开连接