首页 新闻 会员 周边 捐助

网络编程之多人聊天室的bug需修改

0
悬赏园豆:20 [待解决问题]

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("127.0.0.1", 5555)
server.start()

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("127.0.0.1", 5555)
chat_window = ChatWindow(client)
if chat_window.username:
chat_window.mainloop()

为什么当有一个客户端连接了服务器,再次连接一个客户端,第二个客户端发的信息只能看到信息,看不到用户名,怎么修改

Minarui的主页 Minarui | 初学一级 | 园豆:186
提问于:2023-05-29 17:56
< >
分享
所有回答(3)
0

在handle_client方法中,你需要将接收到的消息和用户名一起发送,使得客户端能够在接收到消息后同时看到用户名。修改handle_client方法如下:

def handle_client(self, client):
while True:
try:
message = client.recv(1024)
if message:
username = self.clients[client]
message_with_username = f"{username}: {message.decode('utf-8')}"
self.broadcast(message_with_username.encode('utf-8'), 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 send_message(self):
message = f"{self.username}: {self.entry.get()}\n"
self.entry.delete(0, tk.END)
self.client.send(message.encode('utf-8'))
这样做就可以同时显示用户名和消息了。

lanedm | 园豆:2396 (老鸟四级) | 2023-05-29 22:15

大哥
def send_message(self):
message = f"{self.username}: {self.entry.get()}\n"
self.entry.delete(0, tk.END)
self.client.send(message.encode('utf-8'))
这个是修改的上面的send_message还是下面的send_message,如果是下面的send_message,那个entry的问题怎么解决?这个引起报错了

支持(0) 反对(0) Minarui | 园豆:186 (初学一级) | 2023-05-29 22:43

@难亦: 改下面的send_message(当客户端发送消息时,需要将消息和用户名一起发送),回答了都不看字,报错就调试一下,先把报错的代码去掉,让它能运行,这个完全盲写的代码只是说个意思,你改出的代码能符合需求就行

支持(1) 反对(0) lanedm | 园豆:2396 (老鸟四级) | 2023-05-30 08:27
0

在提供的代码中,当第二个客户端连接并发送消息时,只会在聊天窗口中显示消息文本,而没有显示用户名。这是因为在ChatWindow类的display_received_message方法中,只是简单地将消息文本追加到聊天窗口中,而没有包含用户名。

要修改代码以显示用户名和消息,可以在接收到消息后,将用户名和消息文本一起显示。以下是对display_received_message方法的修改:

python
Copy code
def display_received_message(self, message):
username, message_text = message.split(": ", 1) # 解析出用户名和消息文本
display_message = f"{username}: {message_text}"
self.chat_text.config(state=tk.NORMAL)
self.chat_text.insert(tk.END, display_message + "\n")
self.chat_text.config(state=tk.DISABLED)
这样修改后,当收到消息时,会从消息文本中解析出用户名和实际消息,然后将它们一起显示在聊天窗口中。

请注意,上述修改假设消息文本的格式为“用户名: 消息”。如果实际情况有所不同,你需要根据消息文本的格式进行相应的解析修改。

Technologyforgood | 园豆:7603 (大侠五级) | 2023-05-30 22:57
0

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, username))
            thread.start()
        else:
            client.send("USERNAME_TAKEN".encode("utf-8"))
            client.close()

def handle_client(self, client, username):
    while True:
        try:
            message = client.recv(1024)
            if message:
                self.broadcast(f"{username}: {message.decode('utf-8')}".encode("utf-8"), 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("127.0.0.1", 15555)
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.client.close()
    self.destroy()

if name == "main":
client = Client("127.0.0.1", 15555)
chat_window = ChatWindow(client)
if chat_window.username:
chat_window.mainloop()

Minarui | 园豆:186 (初学一级) | 2023-06-05 10:48
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册