Netty使用(1 TIME协议)

TIME协议的介绍  TIME协议 

此协议提供了一个独立于站点的,机器可读的日期和时间信息。时间服务返回的是以秒数,是从1900年1月1日午夜到现在的秒数

详情查看 百度百科

实例功能介绍

在不接受任何请求时他会发送一个含32位的整数的消息,并且一旦消息发送就会立即关闭连接

因为我们将会忽略任何接收到的数据,而只是在连接被创建发送一个消息,所以这次我们不
能使用 channelRead() 方法了,代替他的是,我们需要覆盖 channelActive() 方法

Serverhandler代码

package com.shj.netty.handler;/**
 * Created by shj on 2018/7/19.
 */

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * @version 1.0
 * @className NettyServerHandler
 * @Description
 * DiscardServerHandler 继承自 ChannelInboundHandlerAdapter,这个类实现了
ChannelInboundHandler接口,ChannelInboundHandler 提供了许多事件处理的接口方法,
然后你可以覆盖这些方法。现在仅仅只需要继承 ChannelInboundHandlerAdapter 类而不是你
自己去实现接口方法。 (典型的适配器模式)
 * @Author shj
 * @Date 2018/7/19、18:05
 */
public class NettyTimeServerHandler extends ChannelInboundHandlerAdapter {

//channelActive() 将会在连接被建立并且准备进行通行时被调用
//    因此可以在此方法里完成一个代表当前时间的32位证书消息的构建工作
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
//       为了发送一个新的消息,我们需要分配一个包含这个消息的新的缓冲区,
//        因为需要写入一个32位的整数,因此我们需要一个至少4个字节的ByteBuf
//ChannelHandlerContext.alloc() 得到一个当前的ByteBufAllocator,然后分配一个新的缓冲。
        ByteBuf time=ctx.alloc().buffer(4);
        time.writeInt((int) (System.currentTimeMillis()/1000L+2208988800L));
//ByteBuf这个方法有两个指针,一个对应读操作,一个对应写操作,当你向ByteBuf里写入数据的时候
//写指针的索引就会增加,同时读指针的索引没有变化.读指针索引和写指针索引分别代表了消息的开始和结束
// 所以在使用netty的时候,不要再和NIO一样,调用flip()方法来切换读写
//        此外  ChannelHandlerContext的write()和writeAndFlush()返回的都是ChannelFuture对象
//  一个ChannelFuture代表了一个还没有发生的I/O操作, 即任何一个请求操作都不会马上被执行
//因为在netty中所有的操作都是异步的
//    由于clise()也会返回一个ChannelFuture  意味着可能并不会马上关闭

        ChannelFuture channelFuture =ctx.writeAndFlush(time);
//       因此必须确保write()返回的ChannelFuture完成之后再调用close()
//        然后他的写操作已经完成他会通知他的监听者
//        此处是在ChannelFuture上增加一个ChannelFutureListener监听器
//        如果完成了写的操作,关闭channel
        channelFuture.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                assert  channelFuture==future;
                ctx.close();
            }
        });


    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//       出现异常就关闭连接
        cause.printStackTrace();
        ctx.close();
    }
}

server 代码

package com.shj.netty.server;

import com.shj.netty.handler.NettyTimeServerHandler;
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;

/**
 * @version 1.0
 * @className NettyTimeServer
 * @Description
 * @Author shj
 * @Date 2018/7/20、13:55
 */
public class NettyTimeServer {

    public static void main(String[] args) {
        EventLoopGroup bossGroup=new NioEventLoopGroup();
        EventLoopGroup workerGroup=new NioEventLoopGroup();

        try {

            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup)

                    .channel(NioServerSocketChannel.class)

                    .childHandler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new NettyTimeServerHandler());
                        }
                    })

                    .option(ChannelOption.SO_BACKLOG,128)

                    .childOption(ChannelOption.SO_KEEPALIVE,true);

//            绑定端口,开始接受进来的连接
            ChannelFuture channelFuture =serverBootstrap.bind(888).sync();
//          等待服务器 socket关闭
            channelFuture.channel().closeFuture().sync();


        }catch (Exception e){
            e.printStackTrace();
        }finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }


    }





}

clientHandler代码

package com.shj.netty.handler;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.Date;

/**
 * @version 1.0
 * @className NettyTimeClientHandler
 * @Description
 * @Author shj
 * @Date 2018/7/20、13:57
 */
public class NettyTimeClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf= (ByteBuf) msg;

try{
   
    long  currentTime=(byteBuf.readUnsignedInt() - 2208988800L) * 1000L;;
    System.out.println(new Date(currentTime));
    ctx.close();

}finally {
byteBuf.release();
}

    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();

    }
}

client代码

package com.shj.netty.client;

import com.shj.netty.handler.NettyTimeClientHandler;
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;

/**
 * @version 1.0
 * @className NettyTimeClient
 * @Description
 * @Author shj
 * @Date 2018/7/20、11:45
 */
public class NettyTimeClient {


    public static void main(String[] args) {
String host="127.0.0.1";
int  port=888;
        EventLoopGroup eventLoopGroup=new NioEventLoopGroup();

        try {
//            Bootstrap 与serverBootstrap类似,只是他是相对于非服务端的channel而言的
//           例如客户端或者无线传输模式的channel,那么它既是bossgroup,也是workerGroup
//            尽管客户端不需要使用到boss worker
            Bootstrap  bootstrap=new Bootstrap();
//            如果只指定了一个EventLoopGroup
            bootstrap.group(eventLoopGroup)
//                    NioSocketChannel 在客户端channel被创建时使用
                    .channel(NioSocketChannel.class)
//
                    .option(ChannelOption.SO_KEEPALIVE,true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new NettyTimeClientHandler());
                        }
                    });
//            启动客户端
            ChannelFuture channelFuture=bootstrap.connect(host,port).sync();

//            等待连接关闭
            channelFuture.channel().closeFuture().sync();
        }catch (Exception e){

        }finally {
        eventLoopGroup.shutdownGracefully();
        }

 }

}

测试结果

1 运行server 

2 运行client

然后就可以看到

client 的控制台输出时间

猜你喜欢

转载自blog.csdn.net/aa15237104245/article/details/81128953