Пример #1
0
    def _reader(self, number):
        # The function must not be called if it does not return with no data with a smaller size as parameter
        if not self.io:
            self.close()
            raise NotConnected('Trying to read on a closed TCP conncetion')
        if number == 0:
            yield ''
            return

        while not self.reading():
            yield ''
        data = ''
        reported = ''
        while True:
            try:
                while True:
                    if self.defensive and random.randint(0, 2):
                        raise socket.error(errno.EAGAIN,
                                           'raising network error in purpose')

                    read = self.io.recv(number)
                    if not read:
                        self.close()
                        self.logger.wire("%s %s lost TCP session with peer" %
                                         (self.name(), self.peer))
                        raise LostConnection(
                            'the TCP connection was closed by the remote end')
                    data += read

                    number -= len(read)
                    if not number:
                        self.logger.wire(
                            LazyFormat(
                                "%s %-32s RECEIVED " %
                                (self.name(), '%s / %s' %
                                 (self.local, self.peer)), read))
                        yield data
                        return

                    yield ''
            except socket.timeout, exc:
                self.close()
                self.logger.wire("%s %s peer is too slow" %
                                 (self.name(), self.peer))
                raise TooSlowError(
                    'Timeout while reading data from the network (%s)' %
                    errstr(exc))
            except socket.error, exc:
                if exc.args[0] in error.block:
                    message = "%s %s blocking io problem mid-way through reading a message %s, trying to complete" % (
                        self.name(), self.peer, errstr(exc))
                    if message != reported:
                        reported = message
                        self.logger.wire(message, 'debug')
                    yield ''
                elif exc.args[0] in error.fatal:
                    self.close()
                    raise LostConnection('issue reading on the socket: %s' %
                                         errstr(exc))
                # what error could it be !
                else:
                    self.logger.wire(
                        "%s %s undefined error reading on socket" %
                        (self.name(), self.peer))
                    raise NetworkError(
                        'Problem while reading data from the network (%s)' %
                        errstr(exc))