通过 sock.recv() 调用获取存储在 Python 的 socketserver.TCPServer 上的消息
我有以下简化的项目结构:
tcp-test-project/
|
+-- server.py
+-- client.py
server.py
包含以下内容:
from socketserver import ThreadingTCPServer, StreamRequestHandler
LOCALHOST = "127.0.0.1"
PORT = 8000
class MsgQueueServer:
def __init__(self, port):
self.port = port
self.msg_q = []
def start(self):
print(f"starting MsgQueueServer at {LOCALHOST}:{self.port}")
with MsgQueueTCPServer((LOCALHOST, self.port), MyMessageHandler, self.msg_q) as server:
server.serve_forever()
class MsgQueueTCPServer(ThreadingTCPServer):
def __init__(self, host_port_tup, request_handler, msg_q):
super().__init__(host_port_tup, request_handler)
self.msg_q = msg_q
class MyMessageHandler(StreamRequestHandler):
def handle(self):
self.cmd, self.msg = self.rfile.readline().decode().split(":", maxsplit=1)
self._get_cmd_handler()()
def _get_cmd_handler(self):
return {
"/NEW": self._recv_message,
"/GET": self._send_messages,
}[self.cmd]
def _recv_message(self):
self.server.msg_q.append(self.msg)
print(f"server message queue contains messages: {self.server.msg_q}")
def _send_messages(self):
print("sending messages in msg_q to client...")
for msg in self.server.msg_q:
self.wfile.write(bytes(msg, "utf-8"))
if __name__ == "__main__":
server = MsgQueueServer(PORT)
server.start()
client.py
是:
import socket
class MsgQueueClient:
def __init__(self, server_addr):
self.host, port = server_addr.split(":")
self.port = int(port)
def send_message(self, message):
"""Send a message to the server."""
cmd = "/NEW"
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((self.host, self.port))
sock.send(bytes(f"{cmd}:{message}", "utf-8"))
print(f"sent message: '{message}' to MsgQueueServer at {self.host}:{self.port}")
def get_messages(self):
"""Fetch a list of all messages stored by the server."""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((self.host, self.port))
sock.send(bytes("/GET:", "utf-8"))
print("waiting on message from server...")
received = str(sock.recv(1024), "utf-8")
print(received)
if __name__ == "__main__":
server_addr = "127.0.0.1:8000"
client = MsgQueueClient(server_addr)
client.send_message("Hello")
client.send_message("World")
client.get_messages()
现在,在 shell 提示符下,项目根目录作为我的 CWD,我开始服务器:
$ python3 server.py
starting MsgQueueServer at 127.0.0.1:8000
在一个新的 shell 中,我运行客户端:
$ python3 client.py
sent message: 'Hello' to MsgQueueServer at 127.0.0.1:8000
sent message: 'World' to MsgQueueServer at 127.0.0.1:8000
waiting on message from server...
此时,如果我调出服务器进程的标准输出,我会看到以下内容:
$ python3 server.py
starting MsgQueueServer at 127.0.0.1:8000
server message queue contains messages: ['Hello']
server message queue contains messages: ['Hello', 'World']
因此,记录的打印语句表明从客户端发送到服务器的两条消息是服务器成功接收并存储到其msg_q
属性。但是,当我尝试通过在客户端中调用 sock.recv(1024)
来检索服务器上存储的消息时,它会阻塞并且不会继续进行通信。
我主要遵循Python文档中的socketserver.TCPServer
示例这里。坦率地说,我没有看到我在这里遗漏了什么,导致我的例子不起作用。非常感谢任何帮助。
I have the following simplified project structure:
tcp-test-project/
|
+-- server.py
+-- client.py
server.py
contains the following:
from socketserver import ThreadingTCPServer, StreamRequestHandler
LOCALHOST = "127.0.0.1"
PORT = 8000
class MsgQueueServer:
def __init__(self, port):
self.port = port
self.msg_q = []
def start(self):
print(f"starting MsgQueueServer at {LOCALHOST}:{self.port}")
with MsgQueueTCPServer((LOCALHOST, self.port), MyMessageHandler, self.msg_q) as server:
server.serve_forever()
class MsgQueueTCPServer(ThreadingTCPServer):
def __init__(self, host_port_tup, request_handler, msg_q):
super().__init__(host_port_tup, request_handler)
self.msg_q = msg_q
class MyMessageHandler(StreamRequestHandler):
def handle(self):
self.cmd, self.msg = self.rfile.readline().decode().split(":", maxsplit=1)
self._get_cmd_handler()()
def _get_cmd_handler(self):
return {
"/NEW": self._recv_message,
"/GET": self._send_messages,
}[self.cmd]
def _recv_message(self):
self.server.msg_q.append(self.msg)
print(f"server message queue contains messages: {self.server.msg_q}")
def _send_messages(self):
print("sending messages in msg_q to client...")
for msg in self.server.msg_q:
self.wfile.write(bytes(msg, "utf-8"))
if __name__ == "__main__":
server = MsgQueueServer(PORT)
server.start()
And client.py
is:
import socket
class MsgQueueClient:
def __init__(self, server_addr):
self.host, port = server_addr.split(":")
self.port = int(port)
def send_message(self, message):
"""Send a message to the server."""
cmd = "/NEW"
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((self.host, self.port))
sock.send(bytes(f"{cmd}:{message}", "utf-8"))
print(f"sent message: '{message}' to MsgQueueServer at {self.host}:{self.port}")
def get_messages(self):
"""Fetch a list of all messages stored by the server."""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((self.host, self.port))
sock.send(bytes("/GET:", "utf-8"))
print("waiting on message from server...")
received = str(sock.recv(1024), "utf-8")
print(received)
if __name__ == "__main__":
server_addr = "127.0.0.1:8000"
client = MsgQueueClient(server_addr)
client.send_message("Hello")
client.send_message("World")
client.get_messages()
Now at a shell prompt with the project root as my CWD, I start the server:
$ python3 server.py
starting MsgQueueServer at 127.0.0.1:8000
In a new shell, I run the client:
$ python3 client.py
sent message: 'Hello' to MsgQueueServer at 127.0.0.1:8000
sent message: 'World' to MsgQueueServer at 127.0.0.1:8000
waiting on message from server...
At this point, if I bring up the stdout of the server process, I see the following:
$ python3 server.py
starting MsgQueueServer at 127.0.0.1:8000
server message queue contains messages: ['Hello']
server message queue contains messages: ['Hello', 'World']
So the logged print statements indicate that two messages sent from the client to the server were successfully received by the server and stored into its msg_q
property. But when I try to retrieve those stored messages on the server through the call to sock.recv(1024)
in the client, it blocks and won't proceed with the communication.
I mostly followed the socketserver.TCPServer
example from Python's docs here. And to be frank, I'm not seeing what I'm missing here that makes my example not work. Any help is greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论