Netty 4.x 实战详解

Netty 4.x 实战详解

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

开发前准备工作:

  • 到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 权威指南
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
包含最新版文档以及全部jar包: jar包如下 netty-buffer-4.1.32.Final-sources.jar netty-buffer-4.1.32.Final.jar netty-build-22-sources.jar netty-build-22.jar netty-codec-4.1.32.Final-sources.jar netty-codec-4.1.32.Final.jar netty-codec-http-4.1.32.Final-sources.jar netty-codec-http-4.1.32.Final.jar netty-codec-http2-4.1.32.Final-sources.jar netty-codec-http2-4.1.32.Final.jar netty-codec-memcache-4.1.32.Final-sources.jar netty-codec-memcache-4.1.32.Final.jar netty-codec-redis-4.1.32.Final-sources.jar netty-codec-redis-4.1.32.Final.jar netty-codec-socks-4.1.32.Final-sources.jar netty-codec-socks-4.1.32.Final.jar netty-codec-stomp-4.1.32.Final-sources.jar netty-codec-stomp-4.1.32.Final.jar netty-common-4.1.32.Final-sources.jar netty-common-4.1.32.Final.jar netty-example-4.1.32.Final-sources.jar netty-example-4.1.32.Final.jar netty-handler-4.1.32.Final-sources.jar netty-handler-4.1.32.Final.jar netty-handler-proxy-4.1.32.Final-sources.jar netty-handler-proxy-4.1.32.Final.jar netty-resolver-4.1.32.Final-sources.jar netty-resolver-4.1.32.Final.jar netty-tcnative-2.0.20.Final-osx-x86_64.jar netty-tcnative-2.0.20.Final-sources.jar netty-transport-4.1.32.Final-sources.jar netty-transport-4.1.32.Final.jar netty-transport-native-epoll-4.1.32.Final-linux-x86_64.jar netty-transport-native-epoll-4.1.32.Final-sources.jar netty-transport-native-kqueue-4.1.32.Final-osx-x86_64.jar netty-transport-native-kqueue-4.1.32.Final-sources.jar netty-transport-native-unix-common-4.1.32.Final-sources.jar netty-transport-native-unix-common-4.1.32.Final.jar netty-transport-rxtx-4.1.32.Final-sources.jar netty-transport-rxtx-4.1.32.Final.jar netty-transport-sctp-4.1.32.Final-sources.jar netty-transport-sctp-4.1.32.Final.jar netty-transport-udt-4.1.32.Final-sources.jar netty-transport-udt-4.1.32.Final.jar
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值