Issue 1736101: asyncore should handle also ECONNABORTED in recv (original) (raw)

client

import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 21)) s.send("sumthin")

server

import asyncore, asynchat import socket import time

class Handler(asynchat.async_chat):

def __init__(self, server, sock, addr):
    asynchat.async_chat.__init__(self, sock)
    self.set_terminator("\n")        
    self.data = ""
    self.respond("Hey there!\r\n")

def respond(self, data):
    print "->" + data
    time.sleep(1)
    self.push(data)

def collect_incoming_data(self, data):
    print "<-" + data
    self.data = self.data + data

def found_terminator(self):
    self.respond(self.data)
    self.data = ''

def handle_close(self):
    remote_ip, remote_port = self.socket.getpeername()
    print "%s:%s disconnected" %(remote_ip, remote_port)
    self.close()

def handle_error(self):
    raise
    

class Server(asyncore.dispatcher):

def __init__(self, address):
    asyncore.dispatcher.__init__(self)
    self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
    self.bind(address)
    self.listen(5)

def handle_accept(self):
    conn, addr = self.accept()
    Handler(self, conn, addr)

address = ('', 21) Server(address) print "server ready." asyncore.loop()

proposed patch

--- line 55

--- line 329 def send(self, data): try: result = self.socket.send(data) return result except socket.error, why: if why[0] == EWOULDBLOCK: return 0

--- line 340 def recv(self, buffer_size): try: data = self.socket.recv(buffer_size) if not data: # a closed connection is indicated by signaling # a read condition, and having recv() return 0. self.handle_close() return '' else: return data except socket.error, why: # winsock sometimes throws ENOTCONN

Re-read the patch. In particular...

@@ -333,9 +349,11 @@ except socket.error, why: if why[0] == EWOULDBLOCK: return 0

That is added handling for all four potential errors in send.