{message}") textwidget.configure(state="disabled") #//////////////////////////////// def recv_message(clientsock, textwidget): while True: try: message= clientsock.recv(1024).decode() if not message: break textwidget.configure(state='normal') textwidget.insert(END, message) textwidget.configure(state='disabled') except: break #//////////////////////////////// def exit(clientsock, username, window): clientsock.sendall(f"[!] El usuario {username} se retir del c"> {message}") textwidget.configure(state="disabled") #//////////////////////////////// def recv_message(clientsock, textwidget): while True: try: message= clientsock.recv(1024).decode() if not message: break textwidget.configure(state='normal') textwidget.insert(END, message) textwidget.configure(state='disabled') except: break #//////////////////////////////// def exit(clientsock, username, window): clientsock.sendall(f"[!] El usuario {username} se retir del c"> {message}") textwidget.configure(state="disabled") #//////////////////////////////// def recv_message(clientsock, textwidget): while True: try: message= clientsock.recv(1024).decode() if not message: break textwidget.configure(state='normal') textwidget.insert(END, message) textwidget.configure(state='disabled') except: break #//////////////////////////////// def exit(clientsock, username, window): clientsock.sendall(f"[!] El usuario {username} se retir del c">
from tkinter import *
import socket
from tkinter.scrolledtext import ScrolledText
import threading
#///////////////////////////////
def send_message( clientsock,username,textwidget, entrywidget):
    message = entrywidget.get()
    clientsock.sendall(f'Username {username} > {message}'.encode())

    entrywidget.delete(0, END)
    textwidget.configure(state="normal")
    textwidget.insert(END, F" \\n{username}>{message}")
    textwidget.configure(state="disabled")
    
#////////////////////////////////

def recv_message(clientsock, textwidget):
    while True:
        try: 
            message= clientsock.recv(1024).decode()
            if not message:
                break
            textwidget.configure(state='normal')
            textwidget.insert(END, message)
            textwidget.configure(state='disabled')
        except:
            break

#////////////////////////////////

def exit(clientsock, username, window):
    clientsock.sendall(f"[!] El usuario {username} se retir del chat".encode())
    clientsock.close()
    window.quit()
    window.destroy()

#////////////////////////////////
def listusernames(clientsock):
    clientsock.sendall("!usuarios".encode())
#////////////////////////////////

def client(): #Funcion Main
    host="localhost"
    port=1234

    clientsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    clientsock.connect((host,port))
    username = input("INGRESE NOMBRE DE URUARIO: ")
    clientsock.sendall(username.encode())

    window= Tk()
    window.title("Chatmultiusuariowaza")
    
    
    textwidget = ScrolledText(window, state="disabled")
    textwidget.pack(padx=5,pady=5)

    frame = Frame(window, bg="red")
    frame.pack(fill=BOTH, expand=1, padx=5)

    entrywidget = Entry(frame)
    entrywidget.bind("<Return>", lambda event: send_message( clientsock, username, textwidget, entrywidget) )
    entrywidget.pack(side=LEFT, fill=BOTH, expand=1, padx=3, pady=3)

    botonenv = Button(frame, text="SEND", command=lambda : send_message(clientsock, username, textwidget, entrywidget))
    botonenv.pack(side=RIGHT, padx=3)
    
    botonuser = Button(frame, text="MOstrar kvros", command = lambda: listusernames(clientsock) )
    botonuser.pack()

    botonsalir = Button(frame, text="Salir del chat", command = lambda: exit(clientsock, username ,window) )
    botonsalir.pack()

    hiloconexionotrousuario = threading.Thread(target=recv_message, args=(clientsock, textwidget))
    hiloconexionotrousuario.daemon = True
    hiloconexionotrousuario.start()

    window.mainloop()
    clientsock.close()

if __name__ == "__main__":
    client()

SERVIDOR

import socket
import threading

def client_thread(sockc, clients,usernames):
    username = sockc.recv(1024).decode()
    usernames[sockc]=username

    for client in clients:
        if client is not sockc:
            client.sendall(f"\\n Se unio al chat: {username}".encode())

    while True:
        try:
            messahge = sockc.recv(1024).decode()

            if messahge == "!usuarios":
                sockc.sendall(f"\\n[+] Todos los usuarios son { ', '.join(usernames.values())}".encode())
                continue

            for client in clients:
                if client is not sockc:
                    client.sendall(f"\\n{messahge}".encode())

        except Exception as e:
            break
        
    sockc.close()
    clients.remove(sockc)
    del clients[sockc]
#////////////////////////////////
def server(): # Funcion main
    host = "localhost"
    port= 1234
    serv= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #Reutilizamos conexion
    serv.bind((host,port))
    serv.listen()

    clients = []
    usernames = {}

    while True:
        sockc, dire = serv.accept() 
        clients.append(sockc) #Agregamos su socket
        hilocliente = threading.Thread(target=client_thread, args=(sockc, clients, usernames)) #proceso de usuario
        hilocliente.deamon = True
        hilocliente.start()

if __name__=="__main__":  server()