为了账号安全,请及时绑定邮箱和手机立即绑定

Netty入门-《客户端-服务端》代码分析

标签:
Java

服务端TimeServer:

package com.wenhy.netty;


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;


public class TimeServer {

    public void bind(int port) throws Exception{

         //配置服务端的NIO线程组

         EventLoopGroup bossGroup = new NioEventLoopGroup();

         EventLoopGroup workerGroup = new NioEventLoopGroup();

         try{

         //netty用于启动NIO服务端的辅助启动类

         ServerBootstrap b = new ServerBootstrap();

         b.group(bossGroup, workerGroup)

            .channel(NioServerSocketChannel.class)

            .option(ChannelOption.SO_BACKLOG, 1024)

            .childHandler(new ChildChannelHandler());//绑定IO事件的处理类,记录日志、对消息进行编解码操作

         //绑定端口,同步等待成功

         ChannelFuture f = b.bind(port).sync();

        

         //等待服务端监听端口关闭

         f.channel().closeFuture().sync();

         } finally{

         //优雅退出,释放资源

         bossGroup.shutdownGracefully();

         workerGroup.shutdownGracefully();

         }

     }

     private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{

         @Override

         protected void initChannel(SocketChannel arg0) throws Exception {

         arg0.pipeline().addLast(new TimeServerHandler());

     }

    

     }

     /**

     * @param args

     * @throws Exception 

     */

     public static void main(String[] args) throws Exception {

         int port = 8080;

         if(args != null && args.length >0 ){

         try {

         port = Integer.valueOf(args[0]);

         } catch (Exception e) {

         }

     }

      new TimeServer().bind(port);

     }

}

TimeServerHandler类:

package com.wenhy.netty;

import io.netty.buffer.ByteBuf;

import io.netty.buffer.Unpooled;

import io.netty.channel.ChannelHandlerContext;

import io.netty.channel.ChannelInboundHandlerAdapter;

public class TimeServerHandler extends ChannelInboundHandlerAdapter  {

@Override

public void channelRead(ChannelHandlerContext ctx, Object msg)

throws Exception {

//将请求的信息放到Netty的ByteBuf对象中,

ByteBuf buf = (ByteBuf) msg;

//通过ByteBuf的readableBytes方法可以获取缓冲区的可读字节数,根据可读字节数创建byte数组,通过ByteBuf的readbyte方法

//将缓冲区中的字节数复制到新建的数组中,

byte[] req = new byte[buf.readableBytes()];

buf.readBytes(req);

String boby = new String(req,"UTF-8");

System.out.println("The time server receive order : " + boby);

String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(boby) ? 

new java.util.Date(System.currentTimeMillis()).toString() : "BAD ORDER";

ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());

ctx.write(resp);

}

@Override

public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

ctx.flush();

}

@Override

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)

throws Exception {

ctx.close();

}

}

客户端TimeClient:

package com.wenhy.netty;


import io.netty.bootstrap.Bootstrap;

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;


public class TimeClient {

public void connect(int port,String host) throws Exception{

//配置客户端NIO线程组

EventLoopGroup group = new NioEventLoopGroup();

try {

Bootstrap b = new Bootstrap();

b.group(group).channel(NioSocketChannel.class)

.option(ChannelOption.TCP_NODELAY, true)

.handler(new ChannelInitializer<SocketChannel>() {


@Override

protected void initChannel(SocketChannel ch)

throws Exception {


ch.pipeline().addLast(new TimeClientHandler());

}

});

//发起异步连接操作

ChannelFuture f = b.connect(host,port).sync();

//等待客户端链路关闭

f.channel().closeFuture().sync();

} finally{

//优雅退出,释放NIO线程组资源

group.shutdownGracefully();

}

}

/**

* @param args

* @throws Exception 

*/

public static void main(String[] args) throws Exception {

int port = 8080;

if(args != null && args.length > 0){

try {

port = Integer.valueOf(args[0]);

} catch (Exception e) {

// TODO: handle exception

}

}

new TimeClient().connect(port, "127.0.0.1");

}

}

TimeClientHandler类:

package com.wenhy.netty;


import java.util.logging.Logger;


import io.netty.buffer.ByteBuf;

import io.netty.buffer.Unpooled;

import io.netty.channel.ChannelHandlerContext;

import io.netty.channel.ChannelInboundHandlerAdapter;


public class TimeClientHandler extends ChannelInboundHandlerAdapter{

private static final Logger logger = Logger.getLogger(TimeClientHandler.class.getName());

private final ByteBuf firstMessgse;

public TimeClientHandler(){

byte[] req = "QUERY TIME ORDER".getBytes();

firstMessgse = Unpooled.buffer(req.length);

firstMessgse.writeBytes(req);

}


/**

* 发送指令,当客户端与服务端建立连接后,Netty 的NIO线程会调用这个方法,发送查询时间的指令

*/

@Override

public void channelActive(ChannelHandlerContext ctx) throws Exception {


//调用这个方法将请求发送给服务端

ctx.writeAndFlush(firstMessgse);

}


/**

* 当服务端返回应答消息时,这个方法会被调用,从Netty的Buf中打印这个应答消息

*/

@Override

public void channelRead(ChannelHandlerContext ctx, Object msg)

throws Exception {

ByteBuf buf = (ByteBuf) msg;

byte[] req = new byte[buf.readableBytes()];

buf.readBytes(req);

String boby = new String(req,"UTF-8");

System.out.println("Now is : "+boby);

}


@Override

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)

throws Exception {

//释放资源

logger.warning("Unexpected exception from downstream : " + cause.getMessage());

ctx.close();

}


}


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
15
获赞与收藏
106

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消