pythonsocketsserverdisconnect

How do I handle a disconnect with python sockets? (ConnectionResetError)


I'm making a simple server and client with python sockets, and I was wondering how I could handle a disconnect. Whenever one of my clients disconnects, it gives a ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host and the server stops running. This makes sense, but how can I handle a disconnect like this? Here is my server code: (I know it's messy its my first socket project)

import socket
import threading


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Connection oriented, IPV4

s.bind((socket.gethostname(), 1234))#Ip address information, port
s.listen(5)

connections = [] #Connection added to this list every time a client connects

def accptconnection():
    while True:
        clientsocket, address = s.accept()
        connections.append(clientsocket) #adds the clients information to the connections array
        threading.Thread(target=recvmsg, args=(clientsocket, address,)).start()

def recvmsg(clientsocket, address):
    while True:
        print(f"Connection from {address} has been established.")
        msg = clientsocket.recv(1024)
        if len(msg.decode('utf-8')) > 0:
            print(msg.decode("utf-8"))
        for connection in connections: #iterates through the connections array and sends message to each one
            msgbreak = msg
            connection.send(bytes(str(msgbreak.decode("utf-8")), "utf-8"))


accptconnection()

Thanks in advance if you help!


Solution

  • This should prevent the server from closing, and clean up clients you had a connection error with:

    import socket
    import threading
    
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Connection oriented, IPV4
    
    s.bind((socket.gethostname(), 1234))#Ip address information, port
    s.listen(5)
    
    connections = [] #Connection added to this list every time a client connects
    
    def accptconnection():
        while True:
            clientsocket, address = s.accept()
            connections.append(clientsocket) #adds the clients information to the connections array
            threading.Thread(target=recvmsg, args=(clientsocket, address,)).start()
    
    def recvmsg(clientsocket, address):
        print(f"Connection from {address} has been established.")
        while True:
            try:
                msg = clientsocket.recv(1024)
            except ConnectionError:
                print(f"Connection from {address} has been lost.")
                if clientsocket in connections:
                    connections.remove(clientsocket)
                return
            if len(msg.decode('utf-8')) > 0:
                print(msg.decode("utf-8"))
            for connection in connections: #iterates through the connections array and sends message to each one
                msgbreak = msg
                try:
                    connection.send(bytes(str(msgbreak.decode("utf-8")), "utf-8"))
                except ConnectionError:
                     print(f"Unable to reach client with socket {connection}")
                     if connection in connections:
                         connections.remove(connection)
    
    accptconnection()