very buggy chat application

I am making a chat application and using tkinter as my gui. The chat does work, but it is very buggy and sometimes doesn't send the message or sometimes repeats the message over and over. I have reviewed the code and can't find where the error is that is causing these bugs.

the code

chat.py

```
from threading import Thread
import time
from tkinter import *
import socket

class ChatRoom(object):
    """
    The GUI of the main chat room.
    - TK scroll bar and TK list box to display messages
    - antiSpam function prevents user from spamming. message cooldown 1s
    this is done to prevent server from breaking
    """

    def __init__(self):
        self.text = ""
        self.text_boxY = 50
        self.ip = socket.gethostbyname(socket.gethostname())
        self.user = ""
        self.isSpamming = False

        self.chat = Tk()
        self.chat.geometry("600x700")

        self.scroll = Scrollbar(self.chat, width=370)
        self.scroll.place(x=300, y=320, anchor=CENTER, height=620)

        self.text_list = Listbox(self.chat, yscrollcommand=self.scroll.set, width=60)
        self.text_list.place(x=300, y=320, anchor=CENTER, height=620)

        self.chat_text = Entry(self.chat, width=40)
        self.chat_text.place(x=400, y=660, anchor=E)

        self.enter = Button(self.chat, text="enter", command=self.showText)
        self.enter.place(x=470, y=660, anchor=W)

        self.anti_spam = Thread(target=self.antiSpam)
        self.anti_spam.start()

    def start(self):
        self.chat.mainloop()

    def showText(self):
        """
        self.ip - the private ip of the user. This is used to separate text messages
        self.text - the text of the user texting
        self.isSpamming - antispam feature to prevent server from breaking
        """

        if not self.isSpamming:
            self.text = self.chat_text.get()

            #cannot send empty string
            if self.text != "":
                self.text_list.insert(END, f"{self.ip} - {self.text}")

            self.text = ""
            self.chat_text.delete(0, END)
        
    def antiSpam(self):
        """
        sets self.isSpamming variable to True when message is sent
        cooldown 1s
        """

        while True:
            if self.text == "":
                self.isSpamming = False

            else:
                self.isSpamming = True
                time.sleep(1)
                self.isSpamming = False

    def getText(self):
        """return text input"""
        return self.text

    def putsText(self, msg):
        """ add text to TK scrollbar """
        self.text_list.insert(END, msg)

if __name__ == '__main__':
    chat = ChatRoom()
```

client.py
```
import socket
from threading import Thread
import time
import chat

host = socket.gethostbyname(socket.gethostname())
port = 9000
addr = (host, port)
exit_msg = "quitx"

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(addr)

chat = chat.ChatRoom()

def get_msg():
    """
    constantly checks for messages from server
    then puts it onto TK scroll bar
    """

    while True:
        # client.recv is blocking
        msg = client.recv(1024).decode()
        chat.putsText(msg)

def send_msg():
    """
    send message to server
    if chat.text is empty, do nothing
    if chat.text is the exit message, close the client and exit

    if no invalid conditions are detected, the message is sent.
    """

    while True:
        if chat.text == "":
            pass

        elif chat.text == exit_msg:
            client.close()
            time.sleep(1)
            exit()

        else:
            client.send(chat.text.encode())

sending = Thread(target=send_msg)
sending.start()

get = Thread(target=get_msg)
get.start()

chat.start()
```

server.py
```
from threading import Thread
import socket

host = "0.0.0.0"
port = 9000
exit_msg = "quitx"
addr = (host, port)

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(addr)

# all connections with the server
clients = []

# listen for 3 connections only
server.listen(3)

def handle_clients():
    """
    checks for incoming connections
    then adds it to clients list

    broadcast that that client has joined with there private ip
    representing the user
    """

    while True:
        client, addr = server.accept()

        clients.append(client)

        broadcast_msg(f"{addr[0]} has joined", client)

def broadcast_msg(msg, client_sent):
    """
    broadcast the message to all the clients

    msg - the message that was sent from one client
    client_sent - the client that sent the message
    this parameter is to prevent the message from the sending
    to the original sender
    """

    for client in clients:
        if client_sent == client:
            pass

        else:
            # close the connection if msg equals to exit_msg (quitx)
            if msg == exit_msg:
                client.send(f"{client.getperrname()[0]} left".encode())
                client.close()
        
            else:
                for client in clients:
                    client.send(msg.encode())

handle = Thread(target=handle_clients)
handle.daemon = True
handle.start()

while True:
    for client in clients:
        #client.recv is blocking.
        msg = client.recv(1024).decode()
        
        #when message is received, broadcast to all
        #clients with client as the original sender
        broadcast_msg(msg, client)
```

i'm using MacOS Python 3.8 conda environment (if this information helps)

Hi @HiImCoder1818,

This issue tracker is for defects in Requests, we won't be able to help debug your code unfortunately. You can try opening a question on a platform like StackOverflow if you need further assistance.