suwoodblender/client.py

239 lines
7.7 KiB
Python
Raw Normal View History

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 <filename> - 获取文件")
print(" 2. save <filename> - 保存文件(会提示输入内容)")
print(" 3. list - 列出文件")
print(" 4. ping - 测试连接")
print(" 5. msg <message> - 发送普通消息")
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()