pythonpython-3.xwindowspython-sockets

My python chat server does not send messages properly


When sending a message for the send time from the client it is not sent to the other client.

I'm fairly new to Python and sockets. some of the commented off code has been code I've tried but has not worked.

My server code:

import socket
import threading

def handle_client(client_socket):
    while True:
        data = client_socket.recv(1024)
        if not data:
            break
        message = data.decode('utf-8')
        message = str(message)

        for i in clients:
            i.send(message.encode('utf-8'))
            # i.sendall(message.encode('utf-8'))
            #i = 0
            
    
        print(f"Received message: {message}")
        #response = "Server received your message: " + message
        #client_socket.sendall(response.encode('utf-8'))
    # client_socket.close()

def main():
    global clients
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    host = '127.0.0.1'
    port = 8080
    server_socket.bind((host, port))
    \# server_socket.listen()
    print(f"Server listening on {host}:{port}")
    clients = \[\]
    names = \[\]

    while True:
        server_socket.listen()
        client_socket, client_address = server_socket.accept()
        Username = client_socket.recv(1024).decode('utf-8')
        names.append(Username)
        clients.append(client_socket)
        print(f"Accepted connection from {client_address} with name {Username}")
        # print(f"CLIENT SOCKET: {client_socket}")
        client_handler = threading.Thread(target=handle_client, args=(client_socket,))
        client_handler.start()

if __name__ == "__main__":
main()

My client code:

import socket
import threading

def recive():
    data = client_socket.recv(1024)
    msg = data.decode('utf-8')
    print(f"{msg}")

def main():
    global client_socket
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    host = '127.0.0.1'
    port = 8080
    Username = input('Username: ')
    client_socket.connect((host, port))
    client_socket.sendall(Username.encode('utf-8'))
    recive_handler = threading.Thread(target=recive)
    recive_handler.start()

    while True:
        message = input("Enter your message: ")
        client_socket.sendall(message.encode('utf-8'))

if __name__ == "__main__":
    main()

I've tried changing sendall() to send(), resetting I in the for loop, and removing client_socket.close()


Solution

  • The main error is that you haven't used the while loop in your receive function of socket client code.

    In your server code, it is not safe when multiple clients connect to the server, and when an error occurs the code will crash.

    I have tested the following codes successfuly.

    The socket server code:

    import socket
    import threading
    
    clients = []
    clients_lock = threading.Lock()
    
    def handle_client(client_socket, client_address):
        while True:
            try:
                data = client_socket.recv(1024)
                if not data:
                    break
    
                message = data.decode('utf-8')
                print(f"Received message from {client_address}: {message}")
    
                # Broadcast message to all clients
                with clients_lock:
                    for client in clients:
                        if client != client_socket:
                            client.sendall(message.encode('utf-8'))
            except ConnectionResetError:
                break
    
        with clients_lock:
            clients.remove(client_socket)
        client_socket.close()
        print(f"Connection closed from {client_address}")
    
    def main():
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        host = '127.0.0.1'
        port = 8080
        server_socket.bind((host, port))
        server_socket.listen()
        print(f"Server listening on {host}:{port}")
    
        while True:
            client_socket, client_address = server_socket.accept()
            print(f"Accepted connection from {client_address}")
    
            with clients_lock:
                clients.append(client_socket)
    
            client_handler = threading.Thread(target=handle_client, args=(client_socket, client_address))
            client_handler.start()
    
    if __name__ == "__main__":
        main()
    

    The socket client code:

    import socket
    import threading
    
    def receive():
        while True:
            try:
                data = client_socket.recv(1024)
                if data:
                    msg = data.decode('utf-8')
                    print(f"Received data: {msg}")
                else:
                    break
            except ConnectionResetError:
                break
    
    def main():
        global client_socket
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        host = '127.0.0.1'
        port = 8080
        client_socket.connect((host, port))
    
        username = input('Username: ')
        client_socket.sendall(username.encode('utf-8'))
    
        receive_handler = threading.Thread(target=receive)
        receive_handler.start()
    
        while True:
            message = input("Enter your message: ")
            if message:
                client_socket.sendall(message.encode('utf-8'))
    
    if __name__ == "__main__":
        main()