The structure design

Channel Of NIO Implementation in io.netty.channel.nio Bao He io.netty.channel.socket.nio In bag , among io.netty.channel.nio It's an abstract implementation ,io.netty.channel.socket.nio Final realization . Here is Channel NIO Derived graph of related classes :

NIO The implementation is ultimately derived 3 A type of NioServerSocketChannel Realized tcp server, NioSocketChannel Realized tcp client, NioDatagramChannel Realized udp socket.

Whole NIO There are three levels of implementation :

AbstractNioChannel Abstraction layer

Yes channel Do the basic initialization , hold channel Set to non-blocking mode .

Realization Channel.Unsafe Of connect Methods the framework , Provided to doConnection, doFinishConnect Two abstract methods , Leave the actual join operation to the subclass implementation .

covers AbstractChannel Of doRegister,doDeregister Method , The positive two methods are implemented Channel Of selectionKey Registration and deregistration .

Realization AbstractChannel Of doClose, This method is not really closed channel action .

Form like doXXX Approach is to ,AbstractChannel Extension point provided , stay <<netty Source code solution analysis (4.0)-3 Channel Abstract implementation >> At the end of , A detailed list of these extension points is given .

AbstractNioByteChannel, AbstractNioMessageChannel Abstraction layer

These two classes are the main implementations read and write Framework , They are implemented in much the same way AbstractNioByteChannel Reading and writing are byte array, and AbstractNioMessageChannel When you read it byte array Convert to structured objects , Serialize structured objects to byte array.

AbstractNioByteChannel Defined 3 Abstract methods to implement real read and write operations : doReadBytes, doWriteBytes, doWriteFileRegion.

AbstractNioMessageChannel The first two 2 Three abstract methods are used to write and write truly structured data types : doReadMessages, doWriteMessage.

NioServerSocketChannel, NioSocketChannel, NioDatagramChannel Final realization

encapsulation NIO API call , real I/O Operating and socket dependent api The calls are implemented at this level .

Usage mode

Have used netty Everyone knows ,netty Provides ServerBootstrap and Bootstrap Class helps users easily create both server-side and client-side applications , But it's not necessary . Only use NioServerSocketChannel, NioSocketChannel, NioDatagramChannel and NioEventLoopGroup You can use development tcp Of server and client, And udp application .

In order for the reader to understand more clearly NioEventLoopGroup and Channel Direct relation , The most primitive USES are given below netty Code for the framework .

tcp server Realization

 import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel; import java.net.InetSocketAddress;
import java.nio.charset.Charset; public class TcpServer {
private NioEventLoopGroup group = new NioEventLoopGroup(); public static void main(String[] argc){
TcpServer server = new TcpServer();
server.start(); while(true){
try{
Thread.sleep(1000);
}catch (Exception e){
break;
}
} server.stop();
} public void start(){
NioServerSocketChannel server = new NioServerSocketChannel(); ChannelPipeline pipleline = server.pipeline();
pipleline.addFirst(new ServerHandler()); group.register(server).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
server.bind(new InetSocketAddress(9001));
System.out.println("server listen add:"+9001);
}
});
}
public void stop(){
group.shutdownGracefully();
} private class ServerHandler extends ChannelInboundHandlerAdapter{ @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{
Channel child = (Channel)msg; child.pipeline().addLast(new ChildHandler()); group.register(child); }
} private class ChildHandler extends ChannelInboundHandlerAdapter{ @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("connected");
} @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("closed");
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{
Channel chnl = ctx.channel();
ByteBuf data = (ByteBuf)msg; System.out.println("recv: "+data.toString(Charset.forName("utf-8")));
chnl.write(msg);
} @Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.channel().flush();
} }
}

One channel After creating , The first thing to do is to pipleline Add handler, And then register it to NioEventLoopGroup in ( The first 31,33 That's ok ). This order cannot be wrong , otherwise ,handler Of handlerAdded,channelRegistered and channelActive Will not be called . When NioServerSocketChannel When a connection is received ,ServerHandler Of course channelRead The method will be called , Is passed in as a parameter , The first 49-53 The line is the initialization code for the new connection .

tcp client Realization

import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel; import java.net.InetSocketAddress;
import java.nio.charset.Charset; public class TcpClient { public static void main(String[] args){
NioEventLoopGroup group = new NioEventLoopGroup(); NioSocketChannel client = new NioSocketChannel();
client.pipeline().addLast(new ClientInboundHandler()); group.register(client); client.connect(new InetSocketAddress(9001)); try{
Thread.sleep(3000);
}catch (Exception e){ }
group.shutdownGracefully();
} private static class ClientInboundHandler extends ChannelInboundHandlerAdapter{
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("connected");
Channel chnl = ctx.channel();
ByteBuf buf = chnl.alloc().buffer();
buf.writeBytes( "this is test".getBytes());
chnl.writeAndFlush(buf);
} @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("closed");
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{
ByteBuf data = (ByteBuf)msg;
System.out.println("recv: "+data.toString(Charset.forName("utf-8")));
ctx.channel().close();
}
} }

client The implementation of the than server Implementation is relatively simple , add to handler,register The order and server Agreement . There is only one channel Sign up to gruop Its methods can only be called after the , Should be channel Most of these methods need to be passed pipleline call , and pipleline Need to be in eventLoop In the implementation of .

udp No, server and client The difference between , This is to make the code clearer , hold server and client Code differentiation .

udp server

import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel; import java.net.InetSocketAddress;
import java.nio.charset.Charset; public class UdpServer { public static void main(String[] args){
NioEventLoopGroup group = new NioEventLoopGroup(); NioDatagramChannel chnl = new NioDatagramChannel();
chnl.pipeline().addLast(new UdpHandler()); group.register(chnl).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
chnl.bind(new InetSocketAddress(9002));
System.out.println("udp bind at:"+9002);
}
}); while(true){
try{
Thread.sleep(1000);
}catch (Exception e){
break;
}
}
group.shutdownGracefully();
}
private static class UdpHandler extends ChannelInboundHandlerAdapter { @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.print("udp channel active");
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{
Channel chnl = ctx.channel();
DatagramPacket pkg = (DatagramPacket)msg;
ByteBuf content = pkg.content();
InetSocketAddress from = pkg.sender();
System.out.println("recv: "+content.toString(Charset.forName("utf-8"))+" from:"+from.toString());
pkg = new DatagramPacket(content, from);
chnl.write(pkg);
} @Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.channel().flush();
}
}
}

udp client

import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel; import java.net.InetSocketAddress;
import java.nio.charset.Charset; public class UdpClient { public static void main(String[] args){
NioEventLoopGroup group = new NioEventLoopGroup(); NioDatagramChannel chnl = new NioDatagramChannel();
chnl.pipeline().addLast(new UdpHandler()); group.register(chnl).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
chnl.bind(new InetSocketAddress(0));
}
}); try{
Thread.sleep(3000);
}catch (Exception e){
}
group.shutdownGracefully();
} private static class UdpHandler extends ChannelInboundHandlerAdapter { @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.print("udp channel active");
Channel chnl = ctx.channel();
ByteBuf content = chnl.alloc().buffer();
content.writeBytes("udp message".getBytes());
chnl.writeAndFlush(new DatagramPacket(content, new InetSocketAddress("127.0.0.1", 9002)));
System.out.println("send message");
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{
DatagramPacket pkg = (DatagramPacket)msg;
ByteBuf content = pkg.content();
InetSocketAddress from = pkg.sender();
System.out.println("recv: "+content.toString(Charset.forName("utf-8"))+" from:"+from.toString());
}
}
}

NioDatagramChannel and NioSocketChannel The initialization process is roughly the same . The difference is ,NioSocketChannel stay connect In the after active state ,NioDatagramChannel Is in bind Then you're in active state .

netty Source code solution analysis (4.0)-11 Channel NIO Realization - More related articles on Overview

  1. netty Source code solution analysis (4.0)-14 Channel NIO Realization : Reading data

      Analysis of this chapter Nio Channel The realization of data reading function of . Channel Reading data requires Channel and ChannelHandler In combination with ,netty The design data reading function includes three elements :Channel, Eve ...

  2. netty Source code solution analysis (4.0)-12 Channel NIO Realization :channel initialization

    Create a channel example , And put it register To eventLoopGroup In the following , This channel And then in a inactive state , Still not available . Only in bind or connect The method is called successfully before ...

  3. netty Source code solution analysis (4.0)-15 Channel NIO Realization : Writing data

    Writing data is NIO Channel Another more complex function implemented . every last channel There is one. outboundBuffer, This is an output buffer . When calling channel Of write Method when writing data , This data is a series of C ...

  4. netty Source code solution analysis (4.0)-13 Channel NIO Realization : Shut down and clean up

    Channel Provides 3 There are two ways to turn off the cleaning function :disconnect,close,deregister. This chapter focuses on this 3 The function of a method NIO Realization . disconnect Realization : disconnect disco ...

  5. netty Source code solution analysis (4.0)-3 Channel Abstract implementation

    AbstractChannel and AbstractUnsafe abstract class io.netty.channel.AbstractChannel Start with this chapter , There will be a lot of space for code analysis . In order to be clear and concise ...

  6. netty Source code solution analysis (4.0)-17 ChannelHandler: IdleStateHandler Realization

    io.netty.handler.timeout.IdleStateHandler The function is to monitor Channel On read, write Or the idle state of both . When Channel When the specified idle time is exceeded , This Ha ...

  7. netty Source code solution analysis (4.0)-18 ChannelHandler: codec-- Codec framework

    The codec framework and some common implementations are located in io.netty.handler.codec In bag . The codec framework consists of two parts :Byte Encoding and decoding between streams and specific types of data , Also called serialization and deserialization . No conversion between types of data . Here's the codec ...

  8. netty Source code solution analysis (4.0)-10 ChannelPipleline Default implementation of -- Event delivery and handling

    Events trigger . Pass on . Processing is DefaultChannelPipleline Another core capability to achieve . In the previous chapter, I roughly talked about the event processing flow , This chapter will analyze all the key details in detail . These key points include : Event triggered interface ...

  9. netty Source code solution analysis (4.0)-20 ChannelHandler: Self implementation of a custom protocol server and client

    This chapter will not directly analyze Netty Source code , But by using Netty The ability to implement a custom protocol for the server and client . Through this practice , Can understand more deeply Netty Related code , At the same time, we can understand , In the process of designing and implementing custom protocol, we need to solve ...

Random recommendation

  1. github add to ssh Method (windows edition )

    Make a new one SSH key open git bash Input   ssh-keygen -t rsa -b 4096 -C "your_email@example.com" Enter a file ...

  2. About eclispe Save settings for automatic code formatting

    Recently in project development , All developers are required to , The code must be formatted and (Ctrl+Shift+F), But sometimes I forget to format , Today, after watching a kind of preservation eclipse You can set the format code automatically 1. Please be here eclipse Settings ...

  3. JIRA 6.3.6 Version deployment

    JIRA 6.3.6 Version deployment Deployment environment :Ubuntu Server .JDK1.7 JIRA file :atlassian-jira-6.3.6.tar.gz Download address : Baidu cloud disk address http://pan. ...

  4. 【bzoj1019】 Hanoi

    [bzoj1019] Hanoi The question Portal :http://www.lydsy.com/JudgeOnline/problem.php?id=1019 analysis Ideas 1: Undetermined coefficient + solve equations set up \(f[n]\) by ...

  5. Ogre Addon And Paged Geometry

    still OGRE Good! , Endless Addon, Endless treasure . both SkyX,Hydrx This kind of sky and water rendering library can be used for learning , also Paged Geometry In this way “ Massive geometry Management system ”. It passes through batch,s ...

  6. Innodb and MyISAM Compare

    Innodb and MyISAM Compare (1)MyISAM Type tables emphasize performance , Its execution speed ratio InnoDB The type is faster (2)MyISAM Unsupported transaction . Foreign keys ,InnoDB Support transactions and foreign keys (3)MyISAM Table level locks used ...

  7. 【 Algorithm series learning 】DP And scrolling arrays [kuangbin Take you fly ] Topic 12 Basics DP1 A - Max Sum Plus Plus

    A - Max Sum Plus Plus https://vjudge.net/contest/68966#problem/A http://www.cnblogs.com/kuangbin/arc ...

  8. win10 System boot password black screen solution

    Method 1 : First step : First, turn on the laptop and turn it on , Enter the power on password to enter The second step : Enter the password and the screen will be black , Press "Ctrl+Alt+Del" Key combination to open Task Manager The third step : In the open Task Manager , Click on &qu ...

  9. thinkphp Store the binary stream of small program code locally

    public function getxcxm(){ $id = input('id'); $astk = json_decode($this->getasstk())->access_t ...

  10. Mysql - Modify field properties in incremental scripts

    When deploying systems incrementally , It is often necessary to provide scripts for incremental modifications , If you are modifying stored procedures or custom functions , That's good to change , Don't worry about the impact on the function of the watch . If it is to change the field ? First of all, I don't know if the field is already in the system , If not , ...