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 {
}
}
今天学习到此结束。
:
还没有评论,来说两句吧...