'Fetching messages stored on Python's socketserver.TCPServer via sock.recv() call
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
