import socket import json import time import sys from datetime import datetime # 设置标准输出编码为 UTF-8(解决 Windows 控制台编码问题) if sys.platform.startswith('win'): import codecs sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach()) sys.stderr = codecs.getwriter('utf-8')(sys.stderr.detach()) # 设置标准输入编码 sys.stdin = codecs.getreader('utf-8')(sys.stdin.detach()) class JSONSocketClient: def __init__(self, host='localhost', port=8888): self.host = host self.port = port self.socket = None self.connected = False def connect(self): """连接到服务器""" try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.connect((self.host, self.port)) self.connected = True print(f"✅ 已连接到服务器 {self.host}:{self.port}") return True except Exception as e: print(f"❌ 连接失败: {e}") return False def disconnect(self): """断开连接""" if self.socket: self.socket.close() self.connected = False print("🔌 已断开连接") def send_request(self, request): """发送请求并接收响应""" if not self.connected: print("❌ 未连接到服务器") return None try: # 发送请求 request_json = json.dumps(request, ensure_ascii=False) self.socket.send(request_json.encode('utf-8')) print(f"📤 发送请求: {request_json}") # 接收响应 response_data = self.socket.recv(4096).decode('utf-8') response = json.loads(response_data) print(f"📥 收到响应: {json.dumps(response, ensure_ascii=False, indent=2)}") return response except Exception as e: print(f"❌ 请求失败: {e}") return None def send_message(self, message): """发送普通消息(非 JSON 格式)""" if not self.connected: print("❌ 未连接到服务器") return None try: self.socket.send(message.encode('utf-8')) print(f"📤 发送消息: {message}") response_data = self.socket.recv(4096).decode('utf-8') response = json.loads(response_data) print(f"📥 收到响应: {json.dumps(response, ensure_ascii=False, indent=2)}") return response except Exception as e: print(f"❌ 发送消息失败: {e}") return None def get_file(self, filename='test_data.json'): """从服务器获取文件""" request = { "command": "get_file", "filename": filename, "timestamp": datetime.now().isoformat() } return self.send_request(request) def save_file(self, filename, content): """保存文件到服务器""" request = { "command": "save_file", "filename": filename, "content": content, "timestamp": datetime.now().isoformat() } return self.send_request(request) def list_files(self): """列出服务器上的 JSON 文件""" request = { "command": "list_files", "timestamp": datetime.now().isoformat() } return self.send_request(request) def ping(self): """测试服务器连接""" request = { "command": "ping", "timestamp": datetime.now().isoformat() } return self.send_request(request) def interactive_mode(self): """交互模式""" print("\n🎮 进入交互模式") print("可用命令:") print(" 1. get - 获取文件") print(" 2. save - 保存文件(会提示输入内容)") print(" 3. list - 列出文件") print(" 4. ping - 测试连接") print(" 5. msg - 发送普通消息") print(" 6. quit - 退出") print() while self.connected: try: command = input("👉 请输入命令: ").strip() if not command: continue parts = command.split(' ', 1) cmd = parts[0].lower() if cmd == 'quit': break elif cmd == 'get': filename = parts[1] if len(parts) > 1 else 'test_data.json' self.get_file(filename) elif cmd == 'save': filename = parts[1] if len(parts) > 1 else 'new_data.json' print("请输入要保存的 JSON 内容(输入空行结束):") lines = [] while True: line = input() if not line: break lines.append(line) if lines: try: content = json.loads('\n'.join(lines)) self.save_file(filename, content) except json.JSONDecodeError as e: print(f"❌ JSON 格式错误: {e}") elif cmd == 'list': self.list_files() elif cmd == 'ping': self.ping() elif cmd == 'msg': message = parts[1] if len(parts) > 1 else "Hello Server!" self.send_message(message) else: print(f"❌ 未知命令: {cmd}") print() # 空行分隔 except KeyboardInterrupt: break except Exception as e: print(f"❌ 命令执行错误: {e}") print("👋 退出交互模式") def test_client(): """测试客户端功能""" client = JSONSocketClient() print("🧪 开始测试客户端...") # 连接服务器 if not client.connect(): return try: # 测试 1: Ping print("\n--- 测试 1: Ping ---") client.ping() # 测试 2: 列出文件 print("\n--- 测试 2: 列出文件 ---") client.list_files() # 测试 3: 获取文件 print("\n--- 测试 3: 获取文件 ---") client.get_file('test_data.json') # 测试 4: 保存文件 print("\n--- 测试 4: 保存文件 ---") test_content = { "message": "这是客户端测试数据", "timestamp": datetime.now().isoformat(), "data": { "name": "测试用户", "age": 25, "hobbies": ["编程", "音乐", "阅读"] } } client.save_file('client_test.json', test_content) # 测试 5: 发送普通消息 print("\n--- 测试 5: 发送普通消息 ---") client.send_message("Hello Server! This is a test message.") print("\n✅ 所有测试完成!") finally: client.disconnect() if __name__ == "__main__": import sys if len(sys.argv) > 1 and sys.argv[1] == 'test': # 运行测试 test_client() else: # 交互模式 client = JSONSocketClient() if client.connect(): try: client.interactive_mode() finally: client.disconnect()