Python Socket发送JSON数据异常:无法流式传输至服务器及客户端
问题排查:流式JSON文本传输失败
我希望将输入文本的每个单词以JSON格式流式发送至服务器,再由服务器转发给所有已连接客户端,但目前数据既未传输到服务器,也未转发给其他客户端。以下是相关代码及运行输出:
客户端代码
import socket import json import threading # 定义服务器IP和端口 SERVER_IP = '44.216.25.181' SERVER_PORT = 55555 # 创建客户端socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect((SERVER_IP, SERVER_PORT)) # 接收服务器消息的函数 def receive_messages(): while True: try: message = client_socket.recv(1024) if not message: break decoded_message = json.loads(message.decode()) message_type = decoded_message.get('type') data = decoded_message.get('data') if message_type == 'stream_text': # 处理流式文本 print(f"Received streamed text: {data.get('chunk')}") except Exception as e: print(f"接收消息出错: {e}") break # 启动接收消息的线程 receive_thread = threading.Thread(target=receive_messages) receive_thread.start() # 向服务器发送JSON消息的方法 def send_message(msg_type, data): try: message = {'type': msg_type, 'data': data} json_data = json.dumps(message) print(json_data) client_socket.send(json_data.encode()) except Exception as e: print(f"发送消息出错: {e}") print("与服务器的连接已关闭。") client_socket.close() def printEvenLengthWords(s): # 分割字符串中的单词 words = s.split() for word in words: print(word) # 修改:将单词包装在字典中,符合服务端预期格式 send_message('stream_text', {'word': word}) # 输入字符串 user_input = input("Enter the text : ") # 调用函数 printEvenLengthWords(user_input)
服务端代码
import socket import threading import json # 定义服务器IP和端口 SERVER_IP = '0.0.0.0' SERVER_PORT = 55555 # 创建服务器socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((SERVER_IP, SERVER_PORT)) server_socket.listen() # 存储已连接客户端的列表 clients = [] # 向所有客户端广播消息的函数 def broadcast(message): # 修改:遍历副本,避免遍历过程中列表变化导致异常 for client in clients.copy(): try: client.send(message) except Exception as e: print(f"广播消息出错: {e}") clients.remove(client) client.close() # 处理客户端连接的函数 def handle_client(client_socket): while True: try: # 接收客户端数据 message = client_socket.recv(1024) if not message: break # 解码JSON消息 decoded_message = json.loads(message.decode()) # 区分消息类型 message_type = decoded_message.get('type') data = decoded_message.get('data') if message_type == 'stream_text': # 修改:获取正确的字段,客户端传的是'word' generated_text = data.get('word') print(f"Received streamed text: {generated_text}") # 将单词按块广播给所有客户端 chunk_size = 5 chunks = [generated_text[i:i + chunk_size] for i in range(0, len(generated_text), chunk_size)] for chunk in chunks: chunk_message = json.dumps({'type': 'stream_text', 'data': {'chunk': chunk}}) # 修改:广播前编码为字节流 broadcast(chunk_message.encode()) except Exception as e: print(f"处理客户端连接出错: {e}") # 移除客户端并关闭连接 if client_socket in clients: clients.remove(client_socket) client_socket.close() break # 接受 incoming 连接,为每个客户端启动新线程 while True: client_socket, client_address = server_socket.accept() clients.append(client_socket) print(f"新客户端连接: {client_address}") client_thread = threading.Thread(target=handle_client, args=(client_socket,)) client_thread.start()
原运行输出
$ python3 client1.py Enter the text : this is a test this {"type": "stream_text", "data": "this"} is {"type": "stream_text", "data": "is"} a {"type": "stream_text", "data": "a"} test {"type": "stream_text", "data": "test"}
问题排查与修复点
- 数据格式不匹配:客户端发送的
data是字符串(如"this"),但服务端尝试用data.get('data')读取字典字段,导致解析失败触发异常,直接断开连接。修复:客户端发送时将单词包装为字典{'word': word},服务端对应读取data.get('word')。 - 广播未编码:服务端广播时直接发送JSON字符串,未编码为字节流,触发发送错误。修复:广播前调用
.encode()将字符串转为字节。 - 语法错误:服务端打印语句
print(f"Received streamed text: {generated_text})")多了一个右括号,导致语法错误。修复:修正括号位置。 - 异常处理不明确:原代码异常捕获太笼统,未打印具体错误信息,难以定位问题。修复:添加具体异常打印。
- 遍历客户端列表风险:原广播函数直接遍历
clients列表,若遍历中客户端断开导致列表变化,会引发异常。修复:遍历列表副本clients.copy()。
内容的提问来源于stack exchange,提问作者noocoder777
相关产品推荐
相关产品推荐

