Netty权威指南之Netty入门应用

本章节需要学习的内容如下:

1、Netty开发环境搭建

2、服务端程序开发NettyServer

3、客户端程序开发NettyClient


第一节:Netty开发环境搭建

(1)、访问Netty的官网http://netty.io,从【Download】标签页下载netty-5.0.0.Alpha2.tar.bz2安装包,安装包不大,14.6M左右。下载完成后,如下截图:


(2)、通过解压缩工具打开压缩工具,如以下截图:


(3)、搭建Netty 应用工程,使用MyEclipse 10 创建普通的Java工程,同时创建Java源文件的package。


(4)、创建第三方类库存放文件夹lib,同时将netty-all-5.0.0.Alpha2.jar文件复制到lib目录下。


到此,Netty应用程序的开发环境已经搭建完毕。


第二节:Netty服务端开发

温故知新:在开始使用Netty开发服务端之前,先回顾一下使用NIO进行服务端开发步骤:

1、创建ServerSocketChannle,并配置它为非阻塞模式。

2、绑定监听,配置TCP参数。比如blocklog大小。

3、创建一个独立的IO线程,用于轮训多路复用器Selector。

4、创建Selector,将之前创建的ServerSocketChannle注册到Selector上,监听SelectKey.Accept.

5、启动IO线程,在循环体中执行Selector.select()方法,轮训就绪的Channle.

6、当轮训到就绪状态的Channle,需要对其判断,如果是SelectorKey.Accept状态,说明是新客户端接入,则调用ServerSocketChannle.accept()的方法接受新的客户端。

7、设置新接入的客户端的链路SocketChannle为非阻塞模式,配置其他的TCP参数。

8、将SocketChannle注册到Selector,监听OP_READ操作位。

9、如果轮训的Channle为OP_READ,则说明SocketChannle中有新的就绪的数据包需要读取,构造ByteBuff对象,读取数据包。

10、如果轮训的Channle的状态为OP_WRITE,说明还有数据没有发送完成,需要继续发送。


分析:一个简单的Java NIO服务端程序,如果我们选择使用Java JDK 的NIO库开发,竟然需要进过繁琐的十几步操作才能完成最基本的信息发送与接受,这也是我们选择Java NIO 开源框架的原因(Netty).

NettyServer.java

package com.nio.server;

import com.nio.handler.NettyServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;



/**
 * Created by vixuan-008 on 2015/6/19.
 */
public class NettyServer {
    public static void main(String[] args)throws Exception{
        int port=17666;
        new NettyServer().bind(port);


    }
    public void bind(int port)throws Exception{
        //配置服务端的NIO线程池
        EventLoopGroup bossGroup=new NioEventLoopGroup();
        EventLoopGroup workGroup=new NioEventLoopGroup();
        try{
            ServerBootstrap b=new ServerBootstrap();
            b.group(bossGroup,workGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG,1024).childHandler(new NettyServerHandler());
            //绑定端口,等待同步成功
            ChannelFuture f=b.bind(port).sync();
            //等待服务端关闭监听端口
            f.channel().closeFuture().sync();

        }finally {
            //释放线程池资源
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();

        }


    }
    //添加内部类
    private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{
        @Override
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            socketChannel.pipeline().addLast(new NettyServerHandler());

        }
    }

}
NettyServerHandler.java

package com.nio.handler;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;




/**
 * Created by vixuan-008 on 2015/6/19.
 */
public class NettyServerHandler extends ChannelHandlerAdapter {
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            ctx.close();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf=(ByteBuf)msg;
        byte[] req=new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body=new String(req,"UTF-8");
        System.out.println("the server receiver data is:"+body);
        String currentTime="time".equalsIgnoreCase(body) ? new java.util.Date(System.currentTimeMillis()).toString():"no zuo no die";
        ByteBuf resp= Unpooled.copiedBuffer(currentTime.getBytes());
        ctx.write(resp);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
        ctx.flush();
    }
}






第三节:Netty客户端开发

NettyClient.java

package com.nio.client;

import com.nio.handler.NettyClientHandler;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;




/**
 * Created by vixuan-008 on 2015/6/19.
 */
public class NettyClient {
    public static void main(String[] args)throws  Exception{
        int port=17666;
        new NettyClient().connect(port,"127.0.0.1");

    }

    public void connect(int port,String host)throws Exception{
        //配置客户端NIO线程池
        EventLoopGroup workGroup=new NioEventLoopGroup();
        try{
            io.netty.bootstrap.Bootstrap b=new io.netty.bootstrap.Bootstrap();
            b.group(workGroup).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY,true).handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    socketChannel.pipeline().addLast(new NettyClientHandler());
                }
            });
            //发起异步连接操作
            ChannelFuture f=b.connect(host,port).sync();
            //等待客户端链路关闭
            f.channel().closeFuture().sync();

        }finally {
            //释放NIO 线程组
            workGroup.shutdownGracefully();

        }
    }


}

NettyClientHandler.java

package com.nio.handler;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

/**
 * Created by vixuan-008 on 2015/6/19.
 */
public class NettyClientHandler extends ChannelHandlerAdapter {
    private final ByteBuf message;

    public NettyClientHandler() {
        byte[] req="time".getBytes();
        message= Unpooled.buffer(req.length);
        message.writeBytes(req);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

        ctx.close();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {

        ctx.writeAndFlush(message);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        ByteBuf buf=(ByteBuf)msg;
        byte[] req=new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body=new String(req,"UTF-8");
        System.out.println("this client receiver data is:"+body);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

    }
}


今天学习到此结束。

:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值