26. Nio (Selector (selector)) handles accept)

Nio (Selector (selector)) handles accept)

Selector (allowing a single thread to manage multiple channels) is actually a case-by-case basis. When no event occurs, it is a blocking thread that stops (the thread takes a break).

This section is about, a server-side serverSocketChannel (used to simulate the server-side) is first registered to the selector, and then the ssckey will be copied to the selector's selectorkeys collection (where the selector is a thing, and the following selector.selectorKeys is a thing). The latter is the channel for the client to establish a connection, and the selectorKeys collection is also used. Finally, he will traverse this collection and print it out. . . (The process of our event is to register first, then copy, and then poll the copied things (our channel is registered to the selector, and the selector will associate a key with the channel. (This key contains all the issues that the channel is concerned about. (three parameters?))))

  1. The selector is non-blocking after the front blocking, that is to say, it is blocking when there is no event, and becomes non-blocking when there is an event. (This selector is enhanced in the previous non-blocking mode. Non-blocking means that the thread is always running ( The blocking method will not let the thread enter the blocking state), the selector makes the thread the blocking state at the beginning (starting from the blocking state))
  2. Let us understand the process. The selector first lets the thread run directly from the blocking mode. If there is an event (the function of the event is to wake up the blocking state (the blocking state becomes the ready state)), then it becomes the ready state Then wait for the cpu scheduling to enter the running state (note here that the selector we mentioned earlier is an upgrade of the blocking state (to make the thread less tired), that is, when it enters the running state, it will be the previous non-blocking mode (blocking method Can't put him in a blocked state)). If there is no event to wake up the blocking state caused by the selector, it will always be in the blocking state. The thread is in a resting state. It does not need to run in non-blocking mode. The selector's select (the bottom layer uses the wait() method )

The first step: we first create the selector selector.open()

Step 2: Register the channel to the selector (this channel must also be non-blocking, that is, channel.configureBlocking(false)) channel.register for registration (selector, what are you interested in,)

Connect, the connection event (TCP connection), corresponds to SelectionKey.OP_CONNECT

Accept, the confirmation event, corresponds to SelectionKey.OP_ACCEPT

Read, a read event, corresponds to SelectionKey.OP_READ, indicating that the buffer is readable.

Write, that is, a write event, corresponds to SelectionKey.OP_WRITE, indicating that the buffer can be written.

Step 3: selector.select method (if there is no time to happen, the thread will be blocked, if there is time to happen, the thread will resume running state (become ready state first))

the fourth step:! ! ! Get a collection of selector.selectorKeys (and the channel registered to the selector (events that are still concerned) are two things). This is to copy the above selector to this for processing. We first get the event collection (is A set collection). If we want to delete, we need to use iterator (Iterator) to traverse (we want to delete when we want to traverse the collection again, we need to use iterator to traverse (if we want to delete when using enhanced for traversal, we will report an error) ))

Step 5: It is me who establishes the connection according to our traversal (selector.selectorKeys)

test:

  1. (First of all, let me talk about our process. At the beginning, we run this server directly, which is the server side. It will only print the ssckey above us (the key (hash) we established with the serverSectorchannel (channel)). Here is the previous one. The channel registered between the server and the selector) they do not have a true infinite loop because there is no client connection event triggered, which is blocked by selector.select. Here is a simple print of the above ser registered to the serverSocketchannel key, stupid

Then we start a client, which will trigger the above interest event, so we will go to a set collection, we will traverse this collection and then print, and finally we will make this connection (according to the previous client connection establishment Connection), the same thing is printed here, that is, we started the server earlier, and registered the severSocketchannel to the seletor. Later, we started the client, and it went down to traverse. Then the ssckey will be copied to the selector's seletorkeys collection (where selector is a thing, and the following selector.selectorKeys is a thing). The latter is the channel for the client to establish a connection, and the selectorKeys collection is also used. Finally, he will traverse this collection and print it out. . .

  1. Let's start another client, where the previous connection ssckey is the same. I thought it was after the connection was established by the interested client, only the last channel was different. Although each client event is monitored, it is different from the channel established by the client. (The selector is an administrator who manages the channel. We used the serverSocketChannel channel to simulate the client (this will always exist as soon as we register))

Summarize:

Let me talk about the understanding of this program. Among them, our ServerSocketChannel is a channel, and its function is to monitor those tcp connections. This accept is the connection establishment. If there is no connection, it is blocked.

Here we demonstrate just a server for clients to connect to us. The meaning of this server is actually just a channel, serverSocketChannel channel. The role of Seletor is to register the channel to the Seletor. Manage multiple channels. Let’s take a look here (before), the upper channel is a server, the lower accept is a connection channel, and the lower read is data reading and writing.

  1. Now our step is to create a selector first,
  2. Then register our server (using the serversocketchannel channel) to the seletor (.register to monitor the occurrence of the event (what event, in that channel), the connection event is monitored here, so as soon as the connection event comes out, it will be detected by the above monitored). After registration, we will give us a key
  3. Indicates what events our listener (administrator) is interested in. (To listen to this exclusive event) In this way, we will register our channel with our seletor.
  4. Here is where we go to see when this event occurs (here is the connection event). How do we know whether our event has occurred? We use the select method of selector. (To solve our previous non-blocking problem (the thread keeps running)) If there is no event, it is blocked, and if there is an event, the thread resumes the running state.
  5. If we have a client connection, then it will run down through the select method above, but how do we deal with this event when we run down. We need to get this event collection first (the above event collection (set)).selectedKeys. It was obtained by the select method in the previous step (what we did at the beginning was to open a client (that is, register the serverSocketchannel to our slector, and no event was monitored (discovered)), so he will be blocked. The select method above,
  6. At this time, we open a client, then this connection event is monitored by us, so the thread starts to run down immediately (from blocking state to running state))

! ! ! The point is, we registered the serverSocketchannel to our selector, which means that the selector has become the administrator, and he has full authority to represent the server, which means that his server is not too much. So when selector listens to our event, he will put this event into the selector's event collection (that is, selector.selectorKeys())

  1. Here is the point. Why do idiots print the same! ! ! Only after we listen to this event and put it in this event collection can we traverse and connect. Accept (that is, the previous one is just a connection request), when we only run this server, what we print is only a server-side address. Later, when our client requests, the key of the server-side channel already exists in the selector. So later we will traverse and print it out to him (it must be the same)

And the channel established by our client accept is different (different from our serverSocketchannel)

Guess you like

Origin blog.csdn.net/logtcm4/article/details/127804054