So I wanted to make a local communicator in Python. I found this guys` tutorial for the server and the client and followed it. But it had one major fraud. You didn't receive other messages until you sent one too. So I modified the client-side code to use multithreading to be able to receive messages without needing to send one.
So now the client side code looks like this:
import socket
import errno
import sys
import threading
HEADER_LENGTH = 10
IP = "127.0.0.1"
PORT = 1234
my_username = input("Username: ")
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
client_socket.setblocking(False)
username = my_username.encode("utf-8")
username_header = f"{len(username):<{HEADER_LENGTH}}".encode("utf-8")
client_socket.send(username_header + username)
def send():
    while True:
        message = input("> ")
        if message:
            message = message.encode("utf-8")
            message_header = f"{len(message):<{HEADER_LENGTH}}".encode("utf-8")
            client_socket.send(message_header + message)
def recieve():
    while True:
        try:
            while True:
                username_header = client_socket.recv(HEADER_LENGTH) # noqa
                if not len(username_header):
                    print("Connection closed by the server")
                    sys.exit()
                username_length = int(username_header.decode("utf-8").strip())
                username = client_socket.recv(username_length).decode("utf-8") # noqa
                message_header = client_socket.recv(HEADER_LENGTH)
                message_length = int(message_header.decode("utf-8").strip())
                message = client_socket.recv(message_length).decode("utf-8")
                print(f"{username} > {message}")
        except IOError as e:
            if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
                print("Reading error: {}".format(str(e)))
                sys.exit()
            continue
        except Exception as e:
            print("Reading error: ".format(str(e)))
            sys.exit()
def start():
    sendth = threading.Thread(target=send)
    recieveth = threading.Thread(target=recieve)
    sendth.start(); recieveth.start()
start()
But then comes another problem. When the user types the message, and during the typing receives a message, the message gets put in the input line, and it just becomes a giant mess.
So is it possible that the receive function/thread outputs the messages in a new window?
I am also open to other solutions to this problem.
 
    