2

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

3 回答 3

2

如果我理解正确,我认为您可能误解了该模块的工作原理。您已经为要绑定的服务器指定了“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 套接字的对象可能会更好,这样服务器 A 处理程序就可以在处理传入请求时获取/释放套接字。

这样,您可以更好地处理服务器 B 断开套接字的情况。您当前的设计将无法很容易地处理损坏的插座。只是一些想法...

于 2009-04-02T22:39:47.617 回答
1

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

例如:TestServer._mySocket = s

于 2009-04-02T18:42:07.110 回答
1

好的,我的主要任务是这个。构建监听服务器(A-server - localhost, 6666),在启动期间将打开到不同服务器(B-server - localhost, 7777)的“硬”连接。当客户向 A-server 发送数据时,此(A-server)将数据(与 B-server 具有硬连接)发送到 B-server,答案从 B-server 接收到 A-server,并将答案发送到客户。再说一遍:客户发送数据,A-server 接收它们,然后发送到 B-server,answer 从 B-server 接收数据,A-server 将数据发送给客户。如此一圈又一圈。与 B 服务器的连接在服务器 A 停止时关闭。以上就是制作这个的考验。

于 2009-04-03T08:06:07.757 回答