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

发布于 2024-07-16 10:41:03 字数 1659 浏览 13 评论 0原文

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

This is problem.
My primary work is : deliver "s" object to "handle" method in TestRequestHandler class.
My first step was : deliver "s" object through "point" method to TestServer class, but here im stuck. How to deliver "s" object to TestRequestHandler? Some suggestions?

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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧瑾黎汐 2024-07-23 10:41:03

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

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

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

如果您想要进一步抽象,看起来您的 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

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

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

If I understand correctly, I think you perhaps are misunderstanding how the module works. You are already specifying an address of 'localhost:6666' for the server to bind on.

When you start the server via your call to serve_forever(), this is going to cause the server to start listening to a socket on localhost:6666.

According to the documentation, that socket is passed to your RequestHandler as the 'request' object. When data is received on the socket, your 'handle' method should be able to recv/send from/to that object using the documented socket API.

If you want a further abstraction, it looks like your RequestHandler can extend from StreamRequestHandler and read/write to the socket using file-like objects instead.

The point is, there is no need for you to create an additional socket and then try to force your server to use the new one instead. Part of the value of the SocketServer module is that it manages the lifecycle of the socket for you.

On the flip side, if you want to test your server from a client's perspective, then you would want to create a socket that you can read/write your client requests on. But you would never pass this socket to your server, per se. You would probably do this in a completely separate process and test your server via IPC over the socket.

Edit based on new information

To get server A to open a socket to server B when server A receives data one solution is to simply open a socket from inside your RequestHandler. That said, there are likely some other design concerns that you will need to address based on the requirements of your service.

For example, you may want to use a simple connection pool that say opens a few sockets to server B that server A can use like a resource. There may already be some libraries in Python that help with this.

Given your current design, your RequestHandler has access to the server as a member variable so you could do something like this:

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

But like I said, it may be better for you to have some sort of connection pool or other object that manages your server B socket such that your server A handler can just acquire/release the socket as incoming requests are handled.

This way you can better deal with conditions where server B breaks the socket. Your current design wouldn't be able to handle broken sockets very easily. Just some thoughts...

荒芜了季节 2024-07-23 10:41:03

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

例如:TestServer._mySocket = s

If the value of s is set once, and not reinitialized - you could make it a class variable as opposed to an instance variable of TestServer, and then have the handler retrieve it via a class method of TestServer in the handler's constructor.

eg: TestServer._mySocket = s

谁人与我共长歌 2024-07-23 10:41:03

好吧,我的主要任务就是这个。 构建监听服务器(A-服务器 - 本地主机,6666),在启动期间将打开与不同服务器(B-服务器 - 本地主机,7777)的“硬”连接。
当客户将数据发送到 A 服务器时,该服务器(A 服务器)将数据(与 B 服务器有硬连接)发送到 B 服务器,答案从 B 服务器接收到 A 服务器,并将答案发送到客户。
再次:客户发送数据,A服务器接收数据,然后发送到B服务器,应答从B服务器接收数据,A服务器将数据发送给客户。
就这样一圈又一圈。 当服务器 A 停止时,与 B 服务器的连接就会关闭。
以上就是制作这个的测试。

Ok, my main task is this. Construction of the listening server (A-server - localhost, 6666) which during start will open "hard" connection to the different server (B-server - localhost, 7777).
When the customer send data to the A-server this (A-server) sends data (having that hard connection to the B-server) to B-server, the answer receives from the B-server to A-server and answer sends to the customer.
Then again : the customer sends data, A-server receives them, then sends to the B-server, the answer receives data from the B-server and A-server send data to the customer.
And so round and round. The connection to the B-server is closes just when the server A will stop.
All above is the test of making this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文