如何将对象的实例传递到的实例SocketServer.BaseRequestHandler?

2024-10-01 09:18:21 发布

您现在位置:Python中文网/ 问答频道 /正文

这就是问题所在。 我的主要工作是:将“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()

Tags: selfdatareturnserverinitaddressrequestdef
3条回答

如果s的值设置了一次,并且没有被重新初始化,那么可以将它作为一个类变量,而不是TestServer的实例变量,然后让处理程序通过处理程序构造函数中的TestServer类方法检索它。在

例如:TestServer.\u mySocket=s

好吧,我的主要任务就是这个。构造侦听服务器(A-server-localhost,6666),在启动期间,它将打开到不同服务器的“硬”连接(B-server-localhost,7777)。 当客户向A服务器发送数据时(A服务器)向B服务器发送数据(与B服务器有硬连接),应答从B服务器接收到A服务器,应答发送给客户。 再次:客户发送数据,A服务器接收数据,然后发送到B服务器,应答从B服务器接收数据,A服务器向客户发送数据。 如此周而复始。与B服务器的连接在服务器A停止时关闭。 所有这些都是做这个的测试。在

如果我理解正确,我想你可能误解了模块的工作原理。您已经指定了地址'本地主机:6666'来绑定服务器。在

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

根据文档,该套接字作为“request”对象传递给您的RequestHandler。当在套接字上接收到数据时,您的“handle”方法应该能够使用文档化的socketapi从该对象接收/发送到该对象。在

如果您需要进一步的抽象,那么您的RequestHandler看起来可以从StreamRequestHandler扩展到使用类似文件的对象的套接字读/写。在

关键是,不需要创建额外的套接字,然后尝试强制服务器使用新的套接字。SocketServer模块的部分价值在于它可以为您管理套接字的生命周期。在

另一方面,如果您想从客户机的角度测试服务器,那么您需要创建一个可以读/写客户机请求的套接字。但你永远不会把这个套接字传递给你的服务器。您可能会在一个完全独立的进程中完成这项工作,并通过套接字上的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

但是,正如我所说的,最好是有某种类型的连接池或其他对象来管理您的serverb套接字,这样您的servera处理程序可以在处理传入请求时获取/释放该套接字。在

这样,您可以更好地处理服务器B中断套接字的情况。你现在的设计不能很容易地处理损坏的插座。只是一些想法。。。在

相关问题 更多 >