pythonmultithreadingsocketstcptimeout

Socket Timeout will kill the Thread in Python


I am going to use the following Python program in my dedicated online server. My doubt is for each and every new connection to server, it is creating a new thread number. I already set the timeout function for the child. It is working fine, but the thread number keeps on increasing. I thought the thread is not clearing properly. Kindly give me the solution to clear or kill the thread process completely.

import socket
from threading import Thread

def on_new_client(client_socket, addr):
while True:
    client_socket.settimeout(10)
    data = client_socket.recv(1024).decode('utf-8')
    client_socket.settimeout(None)
    send="GOK"
    client_socket.send(send.encode())

    if not data:
        print('Disconnected')
        break
    print("Adr and data",addr,data)
client_socket.close()


def main():
host = '127.0.0.1'  # allow any incoming connections
port = 4001

s = socket.socket()
s.bind((host, port))  # bind the socket to the port and ip address
s.listen(5)  # wait for new connections

while True:
    c,addr=s.accept()  # Establish connection with client.
    print("New connection from:",addr)
    thread = Thread(target=on_new_client, args=(c, addr))  # create the thread
    thread.start()  # start the thread
c.close() #c.close()
thread.join()


if __name__ == '__main__':
main()

Solution

  • Your concern is that the threads created for each new client connection are not being cleared properly, which leads to a growing number of threads. To address this, there are two potential causes:

    1. The thread isn't terminating: If the client doesn't disconnect or the on_new_client function gets stuck, the thread might stay alive.

    2. The threads are not being cleaned up: After the thread finishes its work, it may not be properly joined or cleared.

    You can ensure that threads are properly terminated by:

    Improved version of your code:

    import socket
    from threading import Thread
    
    def on_new_client(client_socket, addr):
        try:
            while True:
                client_socket.settimeout(10)
                data = client_socket.recv(1024).decode('utf-8')
                client_socket.settimeout(None)
                
                if not data:
                    print(f'Client {addr} disconnected')
                    break
                
                send = "GOK"
                client_socket.send(send.encode())
                print(f"Address: {addr}, Data: {data}")
        
        except socket.timeout:
            print(f"Connection timed out for {addr}")
        
        except Exception as e:
            print(f"Error with client {addr}: {e}")
        
        finally:
            client_socket.close()
            print(f"Connection closed for {addr}")
    
    def main():
        host = '127.0.0.1'
        port = 4001
    
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind((host, port))
        s.listen(5)
        
        print(f"Server started on {host}:{port}")
        
        while True:
            client_socket, addr = s.accept()
            print(f"New connection from: {addr}")
            
            thread = Thread(target=on_new_client, args=(client_socket, addr), daemon=True)  # Mark thread as daemon
            thread.start()  # Start the thread
    
    if __name__ == '__main__':
        main()
    

    Next Step:

    Add detailed logging for thread and connection status. b. Test the server with multiple connections to verify threads clean up as expected.