Netty学习(一)-引导类

目录

1.引导类类图概览

2.使用

2.1服务端引导类

2.2客户端/无连接引导类

2.3.运行

3.过程分析

3.1 引导客户端/无连接过程

3.2 引导服务端过程


1.引导类类图概览

引导类包内比较简单,大致就4部分:客户端/无连接引导类以及配置、服务端引导类及其配置。类图如下:

Bootstrap
Bootstrap
BootstrapConfig
BootstrapConfig
ServerBootstrapConfig
ServerBootstrap
BootstrapConfig
ServerBootstrapConfig

 

2.使用

2.1服务端引导类

public class EchoServer {

    private final int port;

    public EchoServer(int port) {
        this.port = port;
    }

    public static void main(String[] args) throws Exception {
        if (args.length != 1) {
            System.err.println(
                    "Usage: " + EchoServer.class.getSimpleName() +
                            " <port>");
            return;
        }
        int port = Integer.parseInt(args[0]);        
        new EchoServer(port).start();                
    }

    public void start() throws Exception {
        NioEventLoopGroup group = new NioEventLoopGroup(); 
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(group)                                
                    .channel(NioServerSocketChannel.class)        
                    .localAddress(new InetSocketAddress(port))    
                    .childHandler(new ChannelInitializer<SocketChannel>() { 
                        @Override
                        public void initChannel(SocketChannel ch)
                                throws Exception {
                            ch.pipeline().addLast(
                                    new EchoServerHandler());
                        }
                    });

            ChannelFuture f = b.bind().sync();            
            System.out.println(EchoServer.class.getName() + " started and listen on " + f.channel().localAddress());
            f.channel().closeFuture().sync();            
        } finally {
            group.shutdownGracefully().sync();            
        }
    }

}
@ChannelHandler.Sharable                                        
public class EchoServerHandler extends
        ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx,
                            Object msg) {
        ByteBuf in = (ByteBuf) msg;
        System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8));        
        ctx.write(in);                            
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
                .addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx,
                                Throwable cause) {
        cause.printStackTrace();                
        ctx.close();                            
    }
}

 

2.2客户端/无连接引导类

public class EchoClient {

    private final String host;
    private final int port;

    public EchoClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();                
            b.group(group)                                
                    .channel(NioSocketChannel.class)            
                    .remoteAddress(new InetSocketAddress(host, port))    
                    .handler(new ChannelInitializer<SocketChannel>() {    //5
                        @Override
                        public void initChannel(SocketChannel ch)
                                throws Exception {
                            ch.pipeline().addLast(
                                    new EchoClientHandler());
                        }
                    });

            ChannelFuture f = b.connect().sync();        

            f.channel().closeFuture().sync();            
        } finally {
            group.shutdownGracefully().sync();           
        }
    }

    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            System.err.println(
                    "Usage: " + EchoClient.class.getSimpleName() +
                            " <host> <port>");
            return;
        }

        final String host = args[0];
        final int port = Integer.parseInt(args[1]);

        new EchoClient(host, port).start();
    }
}
@ChannelHandler.Sharable                                
public class EchoClientHandler extends
        SimpleChannelInboundHandler<ByteBuf> {

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", 
                CharsetUtil.UTF_8));
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx,
                             ByteBuf in) {
        System.out.println("Client received: " + in.toString(CharsetUtil.UTF_8));    
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx,
                                Throwable cause) {                    
        cause.printStackTrace();
        ctx.close();
    }
}

2.3.运行

项目使用Maven构建,内含2个子模块,echoserver和echoclient。目录结构如下:

启动netty服务端。打开一个终端,到echoserver目录下执行

mvn exec:java -Dexec.mainClass="com.mclarenp.netty.demo.EchoServer" -Dexec.args="8081"

启动netty客户端。打开另外一个终端,到echoclient目录下执行

mvn exec:java -Dexec.mainClass="com.mclarenp.netty.demo.EchoClient" -Dexec.args="localhost 8081"

看到netty客户端输出:

看到netty服务端输出:

 

3.过程分析

3.1 引导客户端/无连接过程

1)创建Bootstrap来和服务端通道连接

2)给Bootstrap实例指定EventLoopGroup

3)给Bootstrap实例指定Channel

4)给Bootstrap实例指定要连接的服务端IP、端口

5)给Boostrap实例指定Handler。new一个Channel实现类ChannelInitializer,并往ChannelPipeline添加自定义Handler

6)阻塞直到连接完成

7)等待服务器端关闭socket

8)关闭事件循环组

3.2 引导服务端过程

1)创建ServerBootstrap来和监听客户端连接

2)给ServerBootstrap实例指定EventLoopGroup

3)给ServerBootstrap实例指定Channel

4)给ServerBootstrap实例指定要绑定的端口

5)给ServerBoostrap实例指定Handler。new一个Channel实现类ChannelInitializer,并往ChannelPipeline添加自定义Handler

6)阻塞直到服务端启动

7)等待服务器端关闭socket

8)关闭事件循环组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值