The previous article briefly explained the basic concepts of Netty basics:

  • Netty basics

IO of Network programming: When it comes to IO, we have to think of NIO and BIO. When it comes to these two concepts, we have to look at two:

The stream and the channel

Stream is the file I/O stream, Socket I/O stream

We have already known about Channel through previous articles. To summarize the differences:

  • A stream does not automatically buffer data. A channel takes advantage of the system-provided send buffer and receives the buffer (lower level).
  • The stream is only supportedblockingBoth API and channel are supportedblocking,non-blockingAPI, and a network channel can be implemented with a selectormultiplexing
  • Both are full-duplex, i.eRead and writecanAt the same time

⚠ ️ note:

There is a misconception that a stream is one-way and a channel is two-way. So the read and write of a stream may affect each other, which is not true. In network programming, both stream and channel are full-duplex.

Next, I’ll give you a problem that I believe you have encountered. What are the concepts of synchronous blocking, synchronous non-blocking, synchronous multiplexing, asynchronous blocking (no such case), and asynchronous non-blocking? I believe we see these words, not from the head, head a muddled, what is this ghost. First of all, if you want to understand these conceptual properties, you need to start from the IO model.

IO model

There are five IO models:

  1. Blocking IO 2. Non-blocking IO 3. Multiplexing 4. Signal driver 5. Asynchronous I/o

Refer here to the book Unix Network Programming – Volume 1

  • Synchronization: the thread itself retrieves the result (a thread)
  • Asynchronous: threads do not fetch results themselves, but other threads send results (at least two threads)

I want to show you a picture before I explain the concept

The figure consists of two main parts

  • 1. User-level space (equivalent to Java code) 2. Linux kernel space
  • Java code does not have network access to data. It calls the operating system’s kernel space to read the data. This is the switch between user space and system kernel space. Waiting for data: Waiting for client data to be sent. Copying data: Reading data from the network adapter to the memory

When channel.read or stream.read is called once, it switches to the operating system kernel state to complete the actual data reading, which is divided into two stages:

  • Waiting for data phase
  • Replication data phase

  1. What is blocking IO(synchronous)

So the user can’t do anything while they’re reading the data, so that’s blocking IO, right

  1. What is non-blocking IO(synchronous)

When the user reads data, if there is no data, it will return immediately. During this time, the user thread is always running and never stops. This situation is called non-blocking IO.

However, when the user thread discovers that the data is in use, it does not return immediately. It needs to complete the second phase of copying the data. In fact, the user thread is still blocked during the copying process. In simple terms, it is non-blocking while waiting for data and blocking while copying data

This non-blocking IO is not a particularly good improvement, as it involves switching between user program space and Linux kernel space multiple times. Switching too often can affect system performance.

  1. Multiplexing (It's essentially synchronous)

So this is different than either of these, it doesn’t call read, it calls SELECT, and it blocks to see if there’s an event, and once there’s an event, the kernel will tell it that there’s an event, and then the user can get a channel based on selectorkey, and call read, During read, once the data is copied, it still blocks.

  • I’m sure you’ll notice that multiplexing also blocks twice. Is that any different from blocking IO?

    Please check out these two pictures:

Simply put, block IO with Channel2accpetIf channel1 sends another message, blocking IO will not accept the message until channel2 has established a connection.

As shown in the figure, the biggest benefits of multiplexing are: Select can detect events on multiple channels. After the select method is executed, it waits for those events to occur, and whatever event will start running down. If channel1’s read event and Channe2’s Accept event occur at the same time, So select waits to end and returns multiple events.

In conclusion, multiplexing can process events on multiple channels at once

So much for the concept of network IO model, which will be updated in the future

** wechat search [code to meet you] for more exciting content **