Python套接字接收缓冲区处理

时间:2019-04-06 21:17:54

标签: python linux sockets buffer

我正在尝试使用缓冲区/队列来加快python中的套接字处理速度 下面的循环缓冲区实现下面,我用于从用于IPC的localhost套接字读取最大大小

class BufferHandling:
def __init__(self, buffer_size, max_chunk_size):
    self._read_index = 0
    self._write_index = 0

    self._buffer = bytearray(buffer_size)
    self._mem_view = memoryview(self._buffer)
    self._max_size = max_chunk_size

def fill_from_socket(self, _socket):
    logging.debug("2 fill: write index %s , read_index %s", self._write_index , self._read_index)
    if self._read_index > self._write_index:
        if self._read_index - self._write_index < self._max_size:
            raise RuntimeError("no place to write in buffer")

        ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
        self._write_index += ret
        #logging.debug("1 recv_from return with %s, write index %s", ret, self._write_index)
        return

    # write >= read
    _1st_write_size = len(self._mem_view) - self._write_index
    _2nd_write_size = self._read_index

    if _1st_write_size + _2nd_write_size < self._max_size:
        raise RuntimeError("no place to write in buffer")

    if _1st_write_size >= self._max_size:
        ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
        self._write_index += ret
        #logging.debug("2 recv_from return with %s , write index %s", ret, self._write_index)
        return

    # clear some room ...

    self._mem_view[:self._write_index - self._read_index] = self._mem_view[self._read_index: self._write_index]
    self._write_index = self._write_index - self._read_index
    self._read_index = 0
    ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
    self._write_index += ret
    logging.debug("3 recv_from return with %s, write index %s", ret, self._write_index)

"""
# read data from cyclic buffer
# if data found , return data according to _to_read size
# else return empty string
"""
def read_from_buffer(self, _to_read):
    logging.debug("1 write_index %s , read_index %s , _to_read %s", self._write_index, self._read_index, _to_read)
    if self._read_index > self._write_index:
        _1st_read_size = len(self._mem_view) - self._read_index
        _2nd_read_size = self._write_index

        if _1st_read_size >= _to_read:
            data = self._buffer[self._read_index: self._read_index + _to_read]
            self._read_index += _to_read

        else:
            data = self._buffer[self._read_index:] + self._buffer[:_to_read - _1st_read_size]
            self._read_index = _to_read - _1st_read_size
    else: # write >= read
        _read_less = min(_to_read, self._write_index - self._read_index)

        # if self._write_index - self._read_index < _to_read:
        #   logging.debug("2 write_index %s , read_index %s , _to_read %s", self._write_index,self._read_index,_to_read)
        #   #return None

        logging.debug("2 write_index %s , read_index %s , _to_read %s, _read %s", self._write_index, self._read_index, _to_read, _read_less)

        data = self._buffer[self._read_index: self._read_index + _read_less]
        self._read_index += _read_less

    return data

我这样使用它:

        self.__buffer = BufferHandling(self.__LOCALHOST_SOCKET_BUFFER_LEN * 4, 
self.__LOCALHOST_SOCKET_BUFFER_LEN)
data = self.__buffer.read_from_buffer(_to_read)
        if len(data) < _to_read:
            self._selector.select(rlist = [self.__connection], elist = [self.__connection])
            self.__buffer.fill_from_socket(self.__connection)
            data += self.__buffer.read_from_buffer(_to_read)

面对许多问题之后,我的问题是:还有更多Pythonic方式可以得到同样的效果吗? 或建议使用一种更“干净”的方式来获取某种形式的io buffering

0 个答案:

没有答案