Netty 4.x 实战详解

来源:互联网 发布:mac air 电池循环次数 编辑:程序博客网 时间:2024/06/07 05:57

Netty 4.x 实战详解

目前Netty的最新稳定版本是 Netty 4.1.9, 本文根据该版本进行开发介绍。

    • Netty 4x 实战详解
      • 开发前准备工作
      • 代码实现
        • 一 服务器
        • 1服务器启动逻辑DemoServerjava
        • 2服务器Channel通道初始化设置ServerChannelInitializer java
        • 3服务器业务逻辑DemoServerHandlerjava
        • 二 客户端
        • 1客户端启动逻辑DemoClientjava
        • 2客户端Channel通道初始化设置ClientChannelInitializer java
        • 3客户端业务逻辑DemoClientHandlerjava
      • 运行结果
        • 参考书籍Netty in action 和 Netty 权威指南

开发前准备工作:

  • 到Netty官网(http://netty.io/downloads.html),下载开始所需的Netty包:netty-all-4.1.9.Final.jar;

  • 安装Java开发环境,这里使用的是Jdk8;

  • 这里使用的编辑器是Intellij IDEA,也可以根据自己的喜好,选择其他的,比如Eclipse等。


接下来,我们用Netty实现一个demo。主要功能如下:

  • 1、服务端启动,等待接受客户端的连接和处理请求;

  • 2、客户端启动和服务端建立连接,服务器返回“连接成功!”;

  • 3、客户端和服务器进行数据传输操作。


代码实现

这里写图片描述

一、 服务器

1、服务器启动逻辑(DemoServer.java)

package server;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelOption;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;/** * 服务器启动逻辑 */public class DemoServer {    public static void main(String[] args) throws Exception {        int port = 8000;        if (args != null && args.length > 0) {            try {                port = Integer.valueOf(args[0]);            } catch (NumberFormatException e) {                //采用默认值            }        }        new DemoServer().bind(port);    }    public void bind(int port) throws Exception {        //配置服务端的NIO线程组        EventLoopGroup bossGroup = new NioEventLoopGroup();        EventLoopGroup workerGroup = new NioEventLoopGroup();        try {            ServerBootstrap b = new ServerBootstrap();            b.group(bossGroup, workerGroup)                    .channel(NioServerSocketChannel.class)                    .option(ChannelOption.SO_BACKLOG, 1024)                    .childHandler(new ServerChannelInitializer());            //绑定端口,同步等待成功            ChannelFuture f = b.bind(port).sync();            //等待服务器监听端口关闭            f.channel().closeFuture().sync();        } finally {            //优雅退出,释放线程池资源            bossGroup.shutdownGracefully();            workerGroup.shutdownGracefully();        }    }}

2、服务器Channel通道初始化设置(ServerChannelInitializer .java)

import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;/** * 服务器Channel通道初始化设置 */public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {    @Override    protected void initChannel(SocketChannel socketChannel) throws Exception {        ChannelPipeline pipeline = socketChannel.pipeline();        //字符串解码和编码        pipeline.addLast("decoder", new StringDecoder());        pipeline.addLast("encoder", new StringEncoder());        //服务器的逻辑        pipeline.addLast("handler", new DemoServerHandler());    }}

3、服务器业务逻辑(DemoServerHandler.java)

package server;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import java.net.Inet4Address;/** * 服务器业务逻辑 */public class DemoServerHandler extends SimpleChannelInboundHandler {    @Override    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {        System.out.println("Client say : " + msg.toString());        //返回客户端消息 - 我已经接收到了你的消息        ctx.writeAndFlush("Received your message : " + msg.toString());    }    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        System.out.println("RemoteAddress : " + ctx.channel().remoteAddress() + " active !");        ctx.writeAndFlush("连接成功!");        super.channelActive(ctx);    }}

二、 客户端

1、客户端启动逻辑(DemoClient.java)

package client;import io.netty.bootstrap.Bootstrap;import io.netty.channel.Channel;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioSocketChannel;import java.io.BufferedReader;import java.io.InputStreamReader;/** * 客户端启动逻辑 */public class DemoClient {    public static String host = "127.0.0.1"; //服务器IP地址    public static int port = 8000; //服务器端口    public static void main(String[] args) throws Exception {        EventLoopGroup group = new NioEventLoopGroup();        try {            Bootstrap b = new Bootstrap();            b.group(group)                    .channel(NioSocketChannel.class)                    .handler(new ClientChannelInitializer());            //连接客户端            Channel channel = b.connect(host, port).sync().channel();            //控制台输入            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));            for (;;) {                String line = in.readLine();                if (line == null) {                    continue;                }                //向服务端发送数据                channel.writeAndFlush(line);            }        } finally {            //优雅退出,释放线程池资源            group.shutdownGracefully();        }    }}

2、客户端Channel通道初始化设置(ClientChannelInitializer .java)

package client;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;/** * 客户端Channel通道初始化设置 */public class ClientChannelInitializer extends ChannelInitializer<SocketChannel> {    @Override    protected void initChannel(SocketChannel socketChannel) throws Exception {        ChannelPipeline pipeline = socketChannel.pipeline();        //字符串解码和编码        pipeline.addLast("decoder", new StringDecoder());        pipeline.addLast("encoder", new StringEncoder());        //客户端的逻辑        pipeline.addLast("handler", new DemoClientHandler());    }}

3、客户端业务逻辑(DemoClientHandler.java)

package client;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;/** * 客户端业务逻辑 */public class DemoClientHandler extends SimpleChannelInboundHandler {    @Override    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {        System.out.println("Server say : " + msg.toString());    }}

运行结果

  • 先启动服务器,再启动客户端。

这里写图片描述

这里写图片描述

  • 在客户端的控制台输入“服务端,你好!”,然后按“Enter”键,将数据发送到服务端。

这里写图片描述

这里写图片描述

参考书籍:Netty in action 和 Netty 权威指南

0 0
原创粉丝点击