Compare commits
2 Commits
d8aa6e3db3
...
0cd6c87c89
Author | SHA1 | Date | |
---|---|---|---|
0cd6c87c89 | |||
eb247f29b5 |
239
CC3.1.py
Normal file
239
CC3.1.py
Normal file
@ -0,0 +1,239 @@
|
||||
import tkinter as tk
|
||||
import socket
|
||||
import json
|
||||
import threading
|
||||
import queue
|
||||
from tkinter import scrolledtext, messagebox
|
||||
|
||||
class ChatClient:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("聊天客户端")
|
||||
self.socket = None
|
||||
self.connected = False
|
||||
self.username = None
|
||||
self.message_queue = queue.Queue()
|
||||
self.network_thread = None
|
||||
|
||||
self.setup_ui()
|
||||
self.check_messages()
|
||||
|
||||
def setup_ui(self):
|
||||
self.login_frame = tk.Frame(self.root)
|
||||
self.login_frame.pack(pady=10)
|
||||
|
||||
tk.Label(self.login_frame, text="用户名:").grid(row=0, column=0)
|
||||
self.username_entry = tk.Entry(self.login_frame)
|
||||
self.username_entry.grid(row=0, column=1)
|
||||
|
||||
tk.Label(self.login_frame, text="密码:").grid(row=1, column=0)
|
||||
self.password_entry = tk.Entry(self.login_frame, show="*")
|
||||
self.password_entry.grid(row=1, column=1)
|
||||
|
||||
self.login_btn = tk.Button(self.login_frame, text="登录", command=self.start_login)
|
||||
self.login_btn.grid(row=2, column=0, pady=5)
|
||||
|
||||
self.register_btn = tk.Button(self.login_frame, text="注册", command=self.start_register)
|
||||
self.register_btn.grid(row=2, column=1, pady=5)
|
||||
|
||||
self.chat_frame = tk.Frame(self.root)
|
||||
|
||||
self.chat_history = scrolledtext.ScrolledText(self.chat_frame, state='disabled')
|
||||
self.chat_history.pack(pady=5, padx=5, fill=tk.BOTH, expand=True)
|
||||
|
||||
self.message_entry = tk.Entry(self.chat_frame)
|
||||
self.message_entry.pack(pady=5, padx=5, fill=tk.X)
|
||||
|
||||
self.send_btn = tk.Button(self.chat_frame, text="发送", command=self.send_message)
|
||||
self.send_btn.pack(pady=5)
|
||||
|
||||
def check_messages(self):
|
||||
try:
|
||||
while True:
|
||||
msg_type, data = self.message_queue.get_nowait()
|
||||
if msg_type == "login_result":
|
||||
self.handle_login_result(data)
|
||||
elif msg_type == "register_result":
|
||||
self.handle_register_result(data)
|
||||
elif msg_type == "chat_message":
|
||||
self.display_message(data)
|
||||
elif msg_type == "error":
|
||||
messagebox.showerror("错误", data)
|
||||
elif msg_type == "disconnect":
|
||||
self.handle_disconnect()
|
||||
except queue.Empty:
|
||||
pass
|
||||
finally:
|
||||
self.root.after(100, self.check_messages)
|
||||
|
||||
def start_network_thread(self, task, *args):
|
||||
if self.network_thread and self.network_thread.is_alive():
|
||||
return False
|
||||
|
||||
self.network_thread = threading.Thread(
|
||||
target=task,
|
||||
args=args,
|
||||
daemon=True
|
||||
)
|
||||
self.network_thread.start()
|
||||
return True
|
||||
|
||||
def start_login(self):
|
||||
if not self.start_network_thread(self.perform_login):
|
||||
messagebox.showwarning("警告", "已有操作正在进行")
|
||||
|
||||
def start_register(self):
|
||||
if not self.start_network_thread(self.perform_register):
|
||||
messagebox.showwarning("警告", "已有操作正在进行")
|
||||
|
||||
def perform_login(self):
|
||||
try:
|
||||
username = self.username_entry.get()
|
||||
password = self.password_entry.get()
|
||||
|
||||
if not username or not password:
|
||||
self.message_queue.put(("error", "用户名和密码不能为空"))
|
||||
return
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(5)
|
||||
try:
|
||||
sock.connect(("localhost", 8888))
|
||||
sock.settimeout(10)
|
||||
|
||||
sock.sendall(json.dumps({
|
||||
"type": "login",
|
||||
"username": username,
|
||||
"password": password
|
||||
}).encode())
|
||||
|
||||
response = sock.recv(1024)
|
||||
if not response:
|
||||
self.message_queue.put(("error", "服务器无响应"))
|
||||
return
|
||||
|
||||
result = json.loads(response.decode())
|
||||
self.message_queue.put(("login_result", (result, sock)))
|
||||
except socket.timeout:
|
||||
self.message_queue.put(("error", "连接超时"))
|
||||
except Exception as e:
|
||||
self.message_queue.put(("error", f"登录错误: {str(e)}"))
|
||||
if sock:
|
||||
sock.close()
|
||||
except Exception as e:
|
||||
self.message_queue.put(("error", f"系统错误: {str(e)}"))
|
||||
|
||||
def perform_register(self):
|
||||
try:
|
||||
username = self.username_entry.get()
|
||||
password = self.password_entry.get()
|
||||
|
||||
if not username or not password:
|
||||
self.message_queue.put(("error", "用户名和密码不能为空"))
|
||||
return
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(5)
|
||||
try:
|
||||
sock.connect(("localhost", 8888))
|
||||
sock.settimeout(10)
|
||||
|
||||
sock.sendall(json.dumps({
|
||||
"type": "register",
|
||||
"username": username,
|
||||
"password": password
|
||||
}).encode())
|
||||
|
||||
response = sock.recv(1024)
|
||||
if not response:
|
||||
self.message_queue.put(("error", "服务器无响应"))
|
||||
return
|
||||
|
||||
result = json.loads(response.decode())
|
||||
self.message_queue.put(("register_result", result))
|
||||
except socket.timeout:
|
||||
self.message_queue.put(("error", "连接超时"))
|
||||
except Exception as e:
|
||||
self.message_queue.put(("error", f"注册错误: {str(e)}"))
|
||||
finally:
|
||||
if sock:
|
||||
sock.close()
|
||||
except Exception as e:
|
||||
self.message_queue.put(("error", f"系统错误: {str(e)}"))
|
||||
|
||||
def handle_login_result(self, data):
|
||||
result, sock = data
|
||||
if result.get("status") == "success":
|
||||
self.socket = sock
|
||||
self.connected = True
|
||||
self.username = self.username_entry.get()
|
||||
self.login_frame.pack_forget()
|
||||
self.chat_frame.pack(fill=tk.BOTH, expand=True)
|
||||
threading.Thread(target=self.receive_messages, daemon=True).start()
|
||||
else:
|
||||
self.message_queue.put(("error", result.get("message", "登录失败")))
|
||||
if sock:
|
||||
sock.close()
|
||||
|
||||
def handle_register_result(self, result):
|
||||
if result.get("success"):
|
||||
messagebox.showinfo("注册成功", "账号注册成功,请登录")
|
||||
else:
|
||||
self.message_queue.put(("error", result.get("message", "注册失败")))
|
||||
|
||||
def send_message(self):
|
||||
message = self.message_entry.get()
|
||||
if not message or not self.connected:
|
||||
return
|
||||
|
||||
try:
|
||||
self.socket.sendall(json.dumps({
|
||||
"type": "chat",
|
||||
"message": message
|
||||
}).encode())
|
||||
self.message_entry.delete(0, tk.END)
|
||||
except Exception as e:
|
||||
self.message_queue.put(("error", f"发送消息失败: {str(e)}"))
|
||||
self.connected = False
|
||||
self.message_queue.put(("disconnect", None))
|
||||
|
||||
def receive_messages(self):
|
||||
while self.connected:
|
||||
try:
|
||||
data = self.socket.recv(1024)
|
||||
if not data:
|
||||
break
|
||||
|
||||
message = json.loads(data.decode())
|
||||
self.message_queue.put(("chat_message", message))
|
||||
except:
|
||||
break
|
||||
|
||||
self.connected = False
|
||||
self.message_queue.put(("disconnect", None))
|
||||
|
||||
def display_message(self, message):
|
||||
self.chat_history.config(state='normal')
|
||||
self.chat_history.insert(tk.END, f"{message.get('user', '系统')}: {message.get('message')}\n")
|
||||
self.chat_history.config(state='disabled')
|
||||
self.chat_history.see(tk.END)
|
||||
|
||||
def handle_disconnect(self):
|
||||
if self.connected:
|
||||
self.socket.close()
|
||||
self.connected = False
|
||||
self.chat_frame.pack_forget()
|
||||
self.login_frame.pack(pady=10)
|
||||
messagebox.showinfo("断开连接", "与服务器的连接已断开")
|
||||
|
||||
def on_closing(self):
|
||||
if self.connected and self.socket:
|
||||
self.socket.close()
|
||||
self.root.destroy()
|
||||
|
||||
if __name__ == "__main__":
|
||||
root = tk.Tk()
|
||||
root.geometry("500x400")
|
||||
client = ChatClient(root)
|
||||
root.protocol("WM_DELETE_WINDOW", client.on_closing)
|
||||
root.mainloop()
|
8
CS3.1.py
8
CS3.1.py
@ -1,4 +1,3 @@
|
||||
|
||||
import threading
|
||||
import json
|
||||
from flask import Flask, jsonify, request
|
||||
@ -7,6 +6,7 @@ import socket
|
||||
app = Flask(__name__)
|
||||
|
||||
socket_server = socket.socket()
|
||||
socket_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
socket_server.bind(("localhost", 8888))
|
||||
active_users = {}
|
||||
chat_connections = []
|
||||
@ -95,7 +95,7 @@ def handle_socket_message(data, addr, conn):
|
||||
active_users[addr[0]] = data['username']
|
||||
chat_connections.append(conn)
|
||||
return {"status": "success", "message": "Login successful"}
|
||||
return {"success": "error", "message": "Invalid credentials"}
|
||||
return {"status": "error", "message": "Invalid credentials"}
|
||||
elif action == 'chat':
|
||||
if addr[0] in active_users:
|
||||
message = {
|
||||
@ -129,7 +129,7 @@ def run_socket_server():
|
||||
conn.sendall(json.dumps(response).encode())
|
||||
except json.JSONDecodeError:
|
||||
conn.sendall(json.dumps(
|
||||
{"success": "error", "message": "Invalid JSON"}
|
||||
{"status": "error", "message": "Invalid JSON"}
|
||||
).encode())
|
||||
except ConnectionResetError:
|
||||
if addr[0] in active_users:
|
||||
@ -145,4 +145,4 @@ if __name__ == '__main__':
|
||||
with get_db_connection() as conn:
|
||||
conn.execute('''CREATE TABLE IF NOT EXISTS users
|
||||
(name TEXT, passwd TEXT)''')
|
||||
app.run(port=5001)
|
||||
app.run(port=5001)
|
Loading…
x
Reference in New Issue
Block a user