As we know, Netty is directly developed with the JDK’s native NIO, which can be said to be an enhancement of JDK NIO, so it is very important to understand the mechanism of JDK NIO, next will introduce the JDK about several very important components of NIO, example source: github.com/jsbintask22…

ByteBuffer introduction

In contrast to JDK BIO, when reading data from a Socket, either client or server, we usually need to read bytes into an array of bytes until the required data length is met:

InputStream is = socket.getInputStream();
byte[] buff = new byte[1024];
int len;

while((len = is.read(buff)) ! = -1) {
    System.out.println("client msg: " + new String(buff, 0, len));
}
Copy the code

The buff here can be thought of as a data container from which all subsequent processing (such as new String here) will be taken.


In NIO programming, this byte array is changed to a reusable container Buffer(java.nio.buffer), which has several subclasses of the same basic type. Its structure is as follows:

n

  1. The position pointer washes a position index that can be read or written to, with the initial state pointing to 0
  2. Limit on behalf ofThe nextThe position that cannot be written or read. The initial position points to n (note that the index starts at 0).
  3. Capacity is always the size of the container, always n
  4. Mark as a flag, when the mark() method is called, position is assigned to mark, so that the next time the reset() method is called, position can be returned to the position of the previous flag. And if you want to reset the complex principle you have to move. Mark <= position <= limit <= capacity

Note that position represents the next position that can be read or written, so both read and write positions are moved.

Buffer using

Take IntBuffer as an example to introduce its use. IntBuffer inherits from Buffer and uses an integer array to store data. Final int[] hb;


  1. Storing data to a container:put(int i);.put(int index, int i);The position pointer is not moved from the store at the specified location.
  2. Get data:int get();.int get(int index);Fetching data from the specified index position does not move the positon position.
  3. Check whether there is valid data: Check whether position is less than limit.return position < limit;
IntBuffer intBuffer = IntBuffer.allocate(10); / / 1
for (int i = 0; i < intBuffer.capacity(); i++) {
    intBuffer.put((i + 1));  / / 2
}

intBuffer.flip();  / / 3
while (intBuffer.hasRemaining()) {  / / 4
    int i = intBuffer.get();  / / 5
    System.out.println(i);
}

intBuffer.rewind();
while (intBuffer.hasRemaining()) {
    int i = intBuffer.get();
    System.out.println(i);
}
Copy the code
  1. Allocate a byte of data, default on the heap (an internal integer of length 10)
  2. Writing data moves position
  3. Reverse the data region and mark the region that has been written with limit and position, i.e. :limit = position; position = 0; remark = -1;
  4. Check whether there is valid data.
  5. Gets the data in the current position pointer and moves it forward

Finally, the differences between rewind, Flip and clear are introduced

  1. Clear to reset all Pointers to their initial state:position = 0; limit = capacity; mark = -1;, typically used when the container needs to be reused to reset after a series of read and write operations.
  2. Flip is used to isolate valid data. For example, after data is put, this method is called to read the datalimit = position; position = 0; remark = -1;
  3. Rewind is used to read data repeatedly after reading data, that is, reset the position pointer to 0.position = 0; mark = -1;

conclusion

  1. In BIO programming, we usually use byte data to write data to sockets or read data to byte data. In NIO, we usually use Buffer to do this. There are several subclasses of basic types, the most common being BufferByteBuffer
  2. Buffer is read and written by moving the position and limit Pointers
  3. Rewind, Flip, and Clear

Extension: For Buffer, allocate an array directly on the heap using the allocate method of subclasses. It can also allocate memory outside the heap, called direct memory, to achieve zero copy and improve efficiency