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