为什么当有一个客户端连接了服务器,再次连接一个客户端,第二个客户端发的信息只能看到信息,看不到用户名,怎么修改?
# server文件:
import socket
import threading
class Server:
def __init__(self, host, port):
self.host = host
self.port = port
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.host, self.port))
self.clients = {}
self.usernames = []
def start(self):
self.server.listen()
print(f"Server started on {self.host}:{self.port}")
while True:
client, addr = self.server.accept()
client.send("USERNAME".encode("utf-8"))
username = client.recv(1024).decode("utf-8")
if username not in self.usernames:
self.usernames.append(username)
self.clients[client] = username
print(f"Connected: {addr}, Username: {username}")
self.broadcast(f"{username} joined the chat!".encode("utf-8"))
thread = threading.Thread(target=self.handle_client, args=(client,))
thread.start()
else:
client.send("USERNAME_TAKEN".encode("utf-8"))
client.close()
def handle_client(self, client):
while True:
try:
message = client.recv(1024)
if message:
self.broadcast(message, client)
except Exception as e:
print(f"Error: {e}")
username = self.clients[client]
self.usernames.remove(username)
del self.clients[client]
client.close()
self.broadcast(f"{username} left the chat!".encode("utf-8"))
break
def broadcast(self, message, sender=None):
for client in self.clients:
if client != sender:
client.send(message)
if __name__ == "__main__":
server = Server("10.41.38.122", 5555)
server.start()
# client文件:
import socket
import threading
import tkinter as tk
from tkinter import simpledialog
class Client:
def __init__(self, host, port):
self.host = host
self.port = port
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client.connect((self.host, self.port))
def send_message(self, message):
self.client.send(message.encode("utf-8"))
def receive_messages(self, callback):
while True:
try:
message = self.client.recv(1024).decode("utf-8")
if message:
callback(message)
except Exception as e:
print(f"Error: {e}")
self.client.close()
break
class ChatWindow(tk.Tk):
def __init__(self, client):
super().__init__()
self.client = client
self.title("Chat Room")
self.geometry("500x400")
self.chat_text = tk.Text(self, wrap=tk.WORD)
self.chat_text.pack(padx=5, pady=5, fill=tk.BOTH, expand=True)
self.chat_text.config(state=tk.DISABLED)
self.entry_frame = tk.Frame(self)
self.entry_frame.pack(padx=5, pady=5, fill=tk.X)
self.message_entry = tk.Entry(self.entry_frame)
self.message_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)
self.send_button = tk.Button(self.entry_frame, text="Send", command=self.send_message)
self.send_button.pack(side=tk.RIGHT)
self.protocol("WM_DELETE_WINDOW", self.close)
self.username = self.get_username()
if self.username:
self.client.send_message(self.username)
thread = threading.Thread(target=self.client.receive_messages, args=(self.display_received_message,))
thread.start()
else:
self.close()
def get_username(self):
username = tk.simpledialog.askstring("Username", "Enter your username:", parent=self)
return username
def send_message(self):
message = self.message_entry.get()
if message:
self.client.send_message(message)
self.display_received_message(f"{self.username}: {message}")
self.message_entry.delete(0, tk.END)
def display_received_message(self, message):
self.chat_text.config(state=tk.NORMAL)
self.chat_text.insert(tk.END, message + "\n")
self.chat_text.config(state=tk.DISABLED)
def close(self):
self.client.send_message("/quit")
self.client.client.close()
self.destroy()
if __name__ == "__main__":
client = Client("10.41.38.122", 5555)
chat_window = ChatWindow(client)
if chat_window.username:
chat_window.mainloop()