Netty (4) - Binary vector ByteBuf

Introduction of a .ByteBuf

In Netty, the communication between the data carrier and the server for the client ByteBuf, i.e. the object-byte blocks.

Here Insert Picture Description

As shown in the following procedure:

/*
     * @Author ARong
     * @Description 接收到服务端消息时触发
     * @Param [ctx, msg]
     * @return void
     **/
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 接收到服务端发送的ByteBuf,进行解析
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println(String.format("服务端读取到数据%s From %s",
                byteBuf.toString(Charset.forName("utf-8")),
                getCurTime()));

        // 构造一个ByteBuf写回给服务端
        ByteBuf byteBuf1 = getByteBuf(ctx);
        ctx.channel().writeAndFlush(byteBuf1);
    }

Two .ByteBuf structure

ByteBufThe structure can be divided into three, namely, discardable byte area, byte area readable, writable byte areas:
[image dump the chain fails, the source station may have security chain mechanism, it is recommended to save the picture directly down Upload (img-GUFiyZnL-1580796362091) ( http://note.youdao.com/yws/res/9905/4BEE1903F64A4BF491681DD8D3CF6FFA)]

  1. The above three paragraphs are to be split up into two pointers, from left to right, followed by a read pointer (readerIndex), the write pointer (writerIndex), then there is a variable Capacity, it represents the total capacity of the underlying memory ByteBuf
  2. Each byte read from a ByteBuf, readerIndex increment 1, ByteBuf which writerIndex-readerIndex total bytes read, whereby it can be deduced when the writerIndex equal readerIndex time, ByteBuf unreadable
  3. Data is written from the point writerIndex part began to write, each write a byte, writerIndex is incremented by one, until to increase capacity, this time, has not written representation ByteBuf
  4. ByteBuf but in fact there is a parameter maxCapacity, when writing data to the ByteBuf, if the capacity is insufficient, then this time can be expansion, until the capacity expansion to maxCapacity, the error will exceed maxCapacity

Three .ByteBuf of API

Related capacity

  1. capacity()

ByteBuf bottom represents the number of occupied bytes of memory (including discarding bytes, the byte read, write bytes), different underlying mechanisms implement a different calculation.

  1. maxCapacity()

Represents the largest number of ByteBuf underlying bytes of memory can be occupied, when writing data to the ByteBuf, if found to be insufficient capacity, the capacity expansion until the expansion to maxCapacity, more than this number, will throw an exception

  1. readableBytes() 与 isReadable()

readableBytes () indicates the number of bytes currently readable ByteBuf, equal to the value writerIndex-readerIndex, if the two are equal, then the unreadable, isReadable () method returns false

  1. writableBytes()、 isWritable() 、maxWritableBytes()

writableBytes () indicates the number of bytes currently ByteBuf written, its value is equal to the capacity-writerIndex, if both are equal, it indicates not writable, isWritable () returns false, but this time, does not write data to the representative of ByteBuf , if found to ByteBuf not write data written into the case, automatically Netty ByteBuf expansion, expansion memory until the size of the bottom maxCapacity, and maxWritableBytes () represents the maximum number of bytes to be written, its value is equal to maxCapacity- writerIndex

Read and write pointers associated API

  1. readerIndex() 与 readerIndex(int)

The former represents the return of the current read pointer readerIndex, which represents the read pointer is provided

2 .writeIndex() 与 writeIndex(int)

The former represents the return current write pointer writerIndex, which represents the write pointer settings

  1. markReaderIndex() 与 resetReaderIndex()

The former represents save the current read pointer up, which represents the restoring previously saved read pointer to the current value, the code is equivalent to the following two

// 代码片段1
int readerIndex = buffer.readerIndex();
// .. 其他操作
buffer.readerIndex(readerIndex);


// 代码片段二
buffer.markReaderIndex();
// .. 其他操作
buffer.resetReaderIndex();

Recommended two code snippets in this way, do not need to define a variable, whether as a buffer state before passing parameters to go, call resetReaderIndex () can be restored to very common in parsing custom protocol packets of time, it is recommended use this to API

  1. markWriterIndex () and resetWriterIndex ()

This role of the pair of API API Similarly, not repeated here

API to read and write

In essence, all about reading and writing ByteBuf can be seen as the place to start from the beginning to read and write data pointer

  1. writeBytes(byte[] src) 、 buffer.readBytes(byte[] dst)

writeBytes () represents the array of bytes which all the data is written src ByteBuf, and readBytes () refers to all of the data inside ByteBuf read dst, dst where the byte size of the array is generally equal readableBytes (), and src length byte array size is typically less writableBytes ()

  1. writeByte(byte b) 、 buffer.readByte()

writeByte () indicates a byte write to ByteBuf, and buffer.readByte () indicates a byte read from ByteBuf, like API also writeBoolean (), writeChar (), writeShort (), writeInt (), writeLong (), writeFloat (), writeDouble () and readBoolean (), readChar (), readShort (), readInt (), readLong (), readFloat (), readDouble ()

Series, the only difference with read and write API similar API also getBytes, getByte () and setBytes (), setByte () it is to get / set does not change the read and write pointers, and read / write pointer will change to read and write, this when parsing the data do pay attention

  1. release() 与 retain()

Since Netty use of external memory heap, and heap memory is not to be outside the direct management of jvm, that is to apply directly to the memory can not be garbage collected, so we need to manually recover. Somewhat similar to the c language inside, apply to the memory must be manually released, otherwise it will cause a memory leak.

Netty ByteBuf by the reference count management, if a place is referenced ByteBuf not need to recover the underlying memory. By default, when a finished creating ByteBuf, it is referred to as 1, and each time The retain () method call, its reference is incremented, () release principle of the method decrements the reference count is one, if it is found after completing Save reference count is 0, then the recovered directly ByteBuf the underlying memory.

  1. slice()、duplicate()、copy()

These three methods which would normally put them together, the three return value is a new ByteBuf objects

  1. slice () method taken from the original ByteBuf section, this data is read from the region between readerIndex to writeIndex, at the same time, the new maximum capacity ByteBuf maxCapacity returned to the original ByteBuf readableBytes of ()
  2. duplicate () method ByteBuf are taken out of the whole, including all data areas (including the available area and discard area), the pointer information.
    slice method will not copy and duplicate data, they only read and write to change the behavior of "shallow copy" by changing the read and write pointers.
  3. copy () will be directly copied from the original ByteBuf all information, including read and write pointers and the corresponding underlying data, therefore, to copy () ByteBuf returned write data will not affect the original ByteBuf"Deep copy."

TIPS:

slice () and duplicate () does not change ByteBuf reference count, it found that the reference count is zero, they begin to release the memory, call these two methods return of ByteBuf will be released after the original ByteBuf call release (), this time If we read them, it will error.

// retainedSlice 等价于
slice().retain();

// retainedDuplicate() 等价于
duplicate().retain()
Published 309 original articles · won praise 205 · Views 300,000 +

Guess you like

Origin blog.csdn.net/pbrlovejava/article/details/104169017