[ python-Patches-1736101 ] asyncore should handle also ECONNABORTED in recv

"SourceForge.net" <[email protected]>
Newsgroups gmane.comp.python.patches
Message-ID <[email protected]>
Patches item #1736101, was opened at 2007-06-12 14:10
Message generated for change (Comment added) made by josiahcarlson
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1736101&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Library (Lib)
Group: Python 2.5
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: billiejoex (billiejoex)
Assigned to: Josiah Carlson (josiahcarlson)
Summary: asyncore should handle also ECONNABORTED in recv

Initial Comment:
asyncore should handle also ECONNABORTED in recv in which case handle_close must be called.
The two programs in attachment, an asyncore based echo-server and a simple client application terminating after having sent some data, shows how the server raises an ECONNABORTED exception.
Note that the exception does not occur if server responds immediatly so I used a time.sleep(1) statement to let internal socket perform send() on the remote 'dead' peer.
Having said that it's probable that ECONNABORTED should be handled also in send method.

Hope this helps.

----------------------------------------------------------------------

>Comment By: Josiah Carlson (josiahcarlson)
Date: 2007-06-13 14:13

Message:
Logged In: YES 
user_id=341410
Originator: NO

Re-read the patch.  In particular...

@@ -333,9 +349,11 @@
         except socket.error, why:
             if why[0] == EWOULDBLOCK:
                 return 0
+            elif why[0] in (ECONNRESET, ENOTCONN, ESHUTDOWN,
ECONNABORTED):
+                self.handle_close()
+                return 0

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


----------------------------------------------------------------------

Comment By: billiejoex (billiejoex)
Date: 2007-06-13 12:03

Message:
Logged In: YES 
user_id=1357589
Originator: YES

Hi, I've seen your patch but it seems to me that it doesn't include
ECONNABORTED handling for send method.

----------------------------------------------------------------------

Comment By: Josiah Carlson (josiahcarlson)
Date: 2007-06-12 17:40

Message:
Logged In: YES 
user_id=341410
Originator: NO

Please see python.org/sf/1736190 for a patch that includes this particular
bugfixe to asyncore, among others.

----------------------------------------------------------------------

Comment By: billiejoex (billiejoex)
Date: 2007-06-12 14:13

Message:
Logged In: YES 
user_id=1357589
Originator: YES

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
- from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \

-      ENOTCONN, ESHUTDOWN, EINTR, EISCONN, errorcode

+ from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \

+     ENOTCONN, ESHUTDOWN, EINTR, EISCONN, ECONNABORTED, errorcode



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

+             elif why[0] == ECONNABORTED:

+                 self.handle_close()

+                 return 0

            else:
                raise
            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

-             if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]:

+             if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN,
ECONNABORTED]:

                self.handle_close()
                return ''
            else:
                raise

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1736101&group_id=5470
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.