Georgey added the comment: I have changed the code to report any error that occurs in receiving message,
and it reports: [WinError10054] An existing connection was forcibly closed by the remote host Well, this error is the one we need to handle, right? A server need to deal with abrupt offlines of clients. Yes the romote host has dropped and connection has been broken, but that does not mean we cannot recall its address. If this is not a bug, I don't know what is a bug in socket module. ---------------------------------------------------------- import socket import select, time import queue, threading ISOTIMEFORMAT = '%Y-%m-%d %X' BUFSIZ = 2048 TIMEOUT = 10 ADDR = ('', 15625) SEG = "◎◎" SEG_ = SEG.encode() active_socks = [] socks2addr = {} server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_sock.bind(ADDR) server_sock.listen(10) active_socks.append(server_sock) mailbox = queue.Queue() #<helper functions> def send(mail): mail_ = SEG_+ mail.encode() ##The SEG_ at the beginning can seperate messeges for recepient when internet busy for sock in active_socks[1:]: try: sock.send(mail_) except: handle_sock_err(sock) def handle_sock_err(sock): try: addr_del = sock.getpeername() except: addr_del = socks2addr[sock] active_socks.remove(sock) socks2addr.pop(sock) sock.close() send("OFFLIN"+str(addr_del) ) #<sub Thread> class Sender(threading.Thread): #process 'mails' - save and send def __init__(self, mailbox): super().__init__() self.queue = mailbox def analyze(self, mail, fromwhere): send( ' : '.join((fromwhere, mail)) ) def run(self): while True: msg, addr = mailbox.get() ### if msg[0] =="sock_err": print("sock_err @ ", msg[1]) #alternative> print("sock_err @ " + repr( msg[1] ) ) #the alternaive command greatly reduces socket closing handle_sock_err(msg[1]) continue self.analyze(msg, addr) sender = Sender(mailbox) sender.daemon = True sender.start() #<main Thread> while True: onlines = list(socks2addr.values()) print( '\n'+time.strftime(ISOTIMEFORMAT, time.localtime(time.time())) ) print( 'online: '+str(onlines)) read_sockets, write_sockets, error_sockets = select.select(active_socks,[],[],TIMEOUT) for sock in read_sockets: #New connection if sock ==server_sock: # New Client coming in clisock, addr = server_sock.accept() ip = addr[0] active_socks.append(clisock) socks2addr[clisock] = addr #Some incoming message from a client else: # Data recieved from client, process it try: data = sock.recv(BUFSIZ) if data: fromwhere = sock.getpeername() mail_s = data.split(SEG_) ##seperate messages del mail_s[0] for mail_ in mail_s: mail = mail_.decode() print("recv>"+ mail) except Exception as err: print( "SOCKET ERROR: "+str(err) ) mailbox.put( (("sock_err",sock), 'Server') ) continue server_sock.close() ========================================================== ---------- resolution: not a bug -> wont fix status: closed -> open _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue28447> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com