Netty框架的基本使用
来源:互联网 发布:淘宝祖国版手办 编辑:程序博客网 时间:2024/06/02 02:36
Java在1.4之前,使用的都是传统的io进行操作的,基于此的socket的通信也是阻塞的;当服务端启动后,需要等待客户端发送过来一个数据才能进行后续操作;此情况下,当有大量的客户端发送请求时,会产生大量的线程,给服务器造成过大的压力。故而在Java 1.4之后引入了一个新的API——Java NIO
NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。
IO
NIO会向当前系统内核注册一个监听器,在客户端消息未发来之前,服务器可以处理其他事物,只有当消息过来时才会触发监听器,服务端开始处理消息。这样一来服务器就可以不用一直处于阻塞状态等待客户端的消息。
现在开始说下封装了NIO连接内核注册监听器的操作的,只需要我们写业务代码的框架Netty
1.下载netty包,下载地址http://netty.io/
2.服务端
package netty.server;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.Channel;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;/** * • 配置服务器功能,如线程、端口 • 实现服务器处理程序,它包含业务逻辑,决定当有一个请求连接或接收数据时该做什么 * @author wb-jlh258576 * */public class EchoServer {private final int port;public EchoServer(int port) {this.port = port;}public void start() throws Exception{ServerBootstrap serverBootstrap = new ServerBootstrap();EventLoopGroup eventLoopGroup = new NioEventLoopGroup();serverBootstrap.group(eventLoopGroup) .channel(NioServerSocketChannel.class) .localAddress("localhost", port) .childHandler(new ChannelInitializer<Channel>() {@Overrideprotected void initChannel(Channel ch) throws Exception {// TODO Auto-generated method stubch.pipeline().addLast(new EchoServerHandler());}});// 最后绑定服务器等待直到绑定完成,调用sync()方法会阻塞直到服务器完成绑定,然后服务器等待通道关闭,因为使用sync(),所以关闭操作也会被阻塞。try {ChannelFuture channelFuture = serverBootstrap.bind().sync();System.out.println("开始监听,端口为:" + channelFuture.channel().localAddress());channelFuture.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();}finally{eventLoopGroup.shutdownGracefully().sync();}}public static void main(String[] args) throws Exception {new EchoServer(8888).start();}}3.服务端处理业务类
package netty.server;import java.util.Date;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;public class EchoServerHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println("server 开始读取数据。。。");ByteBuf buf = (ByteBuf)msg;byte[] req = new byte[buf.readableBytes()];buf.readBytes(req);String body = new String(req, "UTF-8");System.out.println("接收客户端数据:" + body);//向客户端发送数据System.out.println("server向client发送数据。。。");String currentTime = new Date(System.currentTimeMillis()).toString();System.out.println("服务端当前的时间:"+currentTime); ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes()); ctx.write(resp);}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {// TODO Auto-generated method stubSystem.out.println("server 数据处理完毕");ctx.flush();}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {// TODO Auto-generated method stubcause.printStackTrace();ctx.close();}}
package netty.client;import io.netty.bootstrap.Bootstrap;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.Channel;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelHandler;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;import io.netty.channel.socket.nio.NioSocketChannel;import netty.server.EchoServer;import netty.server.EchoServerHandler;public class EchoClient {private final int port;public EchoClient(int port) {this.port = port;}public void start() throws Exception{// 客户端引导类Bootstrap bootstrap = new Bootstrap();EventLoopGroup eventLoopGroup = new NioEventLoopGroup();bootstrap.group(eventLoopGroup) .channel(NioSocketChannel.class) .remoteAddress("localhost", port) .handler(new ChannelInitializer<Channel>() {@Overrideprotected void initChannel(Channel ch) throws Exception {// TODO Auto-generated method stubch.pipeline().addLast(new EchoClientHandler());}});// 链接服务器try {ChannelFuture channelFuture = bootstrap.connect().sync();channelFuture.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();}finally{eventLoopGroup.shutdownGracefully().sync();}}public static void main(String[] args) throws Exception {new EchoClient(8888).start();}}
5.客户端处理业务类(回调)
package netty.client;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelHandler;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println("客户端连接服务器,开始发送数据……");byte[] req = "请求当前服务端时间".getBytes();//消息ByteBuf buffer = Unpooled.buffer(req.length);buffer.writeBytes(req);ctx.writeAndFlush(buffer);}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {// TODO Auto-generated method stubSystem.out.println("client 读取server数据..");// 服务端返回消息后ByteBuf buf = (ByteBuf) msg;byte[] req = new byte[buf.readableBytes()];buf.readBytes(req);String body = new String(req, "UTF-8");System.out.println("服务端当前时间 :" + body);}}
最后服务端的输出结果为
server 开始读取数据。。。接收客户端数据:请求当前服务端时间server向client发送数据。。。服务端当前的时间:Thu Jul 20 14:45:00 CST 2017server 数据处理完毕
客户端的输出结果
客户端连接服务器,开始发送数据……client 读取server数据..服务端当前时间 :Thu Jul 20 14:45:00 CST 2017
值得一提的是,当服务端注册了多个handler时,如果是InboundHandler,执行顺序为注册顺序;如果是OutboundHandler,执行顺序为注册顺序的逆序,且必须有一个InboundHandler在最后注册
阅读全文
0 0
- Netty框架的基本使用
- 开源NIO框架Netty的使用
- Netty—基本使用介绍
- Netty 基本使用,比Mina要稳定的多。
- 使用JAVA操作netty框架
- 使用JAVA操作netty框架
- 使用JAVA操作netty框架
- 使用JAVA操作netty框架
- 使用JAVA操作netty框架
- 使用JAVA操作netty框架
- nio使用之netty框架
- Play框架的基本使用
- DWZ框架的基本使用
- Masonry框架的基本使用
- require框架的基本使用
- Xutil框架的基本使用
- Struts2框架的基本使用
- Struts2框架的基本使用
- NFS服务
- Github删除forked项目
- 跨域资源共享CORS详解
- 20170720工作记账流水
- Java Web学习之路
- Netty框架的基本使用
- 在Windows10下搭建Git服务器 使用COPSSH+msysGit
- haddop2新特性
- web项目页面跳转
- 7种网络编程I/O模型代码实现实例
- 二分查找
- cocos js TextField
- php的两种好用的无限级分类方法
- 签到