难亦 2023-05-29 18:19 采纳率: 0%
浏览 16

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

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




# 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()


  • 写回答

2条回答 默认 最新

  • 鱼弦 全栈领域优质创作者 2023-05-29 20:01
    关注

    当第二个客户端连接到服务器时,它会发送消息,但消息中只包含文本内容,没有包含用户名。这是因为您的客户端代码在发送消息时,只发送了消息的文本内容,没有包含用户名信息。要解决这个问题,您可以修改客户端代码,在发送消息时同时发送用户名信息。

    具体来说,您可以在客户端的send_message方法中,将消息和用户名一起发送,例如:

    def send_message(self, message):
        username_message = self.username + ": " + message
        self.client.send(username_message.encode("utf-8"))
    
    

    这样,当客户端发送消息时,消息中就包含了用户名和文本内容。在服务器端接收到这个消息后,就可以正确地显示用户名和消息内容了。

    同时,您需要在服务器端的handle_client方法中,将接收到的消息分解成用户名和文本内容,例如:

    python
    Copy

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

    这样,服务器端就可以正确地处理包含用户名信息的消息,并将用户名和消息内容一起广播给所有客户端了。

    评论

报告相同问题?

问题事件

  • 修改了问题 5月29日
  • 创建了问题 5月29日

悬赏问题

  • ¥15 本人本科机械,目前研一。没有深度学习基础,目前对研究生课题一片迷茫,请教各位!
  • ¥15 关于R语言单因素与多因素线性回归的平均值
  • ¥15 服务器清除BIOS之后引导不了
  • ¥15 CPLEX用OPL编写的混合整数线性优化问题。
  • ¥15 可以用EasyConnect连接实验室内网,但无法连接内网才能访问的服务器,为什么?
  • ¥15 前端预览docx文件,文件从后端传送过来。
  • ¥15 层次聚类和蛋白质相似度
  • ¥25 主成分分析中的第一第二主成分分别代表哪些参数
  • ¥15 oracle数据库查询语句问题
  • ¥15 有没有c++绘制算法的佬们吗救孩一下