how to know if socket is still connected

John J. Lee jjlee at reportlab.com
Tue Jul 18 19:43:16 EDT 2006


Grant Edwards <grante at visi.com> writes:
[...]
> > Often normal send() and recv() semantics have been mistaught.
> > An alert alien, looking at other common APIs in isolation, 
> > might reasonably wonder whether there is some sort of 
> > still_ok_to_use() sort of check as part of TCP.  As it happens,
> > of course, that doesn't fit with the rest of socket networking,
> > which takes the "modernist" approach of trying send() or recv(),
> > and reporting any exception.
> 
> On most Unices there are some obscure API features that can be
> used to generate a SIGPIPE under some vaguely specified error
> conditions (e.g. TCP keepalive timeout).  I've only read about
> them and never tried to use them, since I couldn't see anything
> in the description of the features that was any benefit over
> the nomral send() and recv() usage.

Sorry for butting in, Grant, but this reminds me of this bug:

http://python.org/sf/1411097


and specifically, of my question in the tracker:

| One problem: I don't understand the need for
| HTTPConnection._safe_read(), rather than checking for an
| EINTR resulting from the recv() call (or WSAEINTR on
| Windows).  Can anybody explain that?


Note the comment in the third paragraph in the method's docstring,
below ("Note that we cannot...", and the "if not chunk" test).  Do you
know of any reason why it should do that (fail to check for EINTR)?
Looks wrong to me.

(I do understand that it's only signals that arrive before *any* data
is read that cause EINTR, but that's the specific case mentioned in
the 3rd para, and a check for that is what's conspicuously absent from
the method implementation.)

    def _safe_read(self, amt):
        """Read the number of bytes requested, compensating for partial reads.

        Normally, we have a blocking socket, but a read() can be interrupted
        by a signal (resulting in a partial read).

        Note that we cannot distinguish between EOF and an interrupt when zero
        bytes have been read. IncompleteRead() will be raised in this
        situation.

        This function should be used when <amt> bytes "should" be present for
        reading. If the bytes are truly not available (due to EOF), then the
        IncompleteRead exception can be used to detect the problem.
        """
        s = []
        while amt > 0:
            chunk = self.fp.read(min(amt, MAXAMOUNT))
            if not chunk:
                raise IncompleteRead(s)
            s.append(chunk)
            amt -= len(chunk)
        return ''.join(s)


John



More information about the Python-list mailing list