io-4-netty-入门程序

来源:互联网 发布:运维可以学windows吗 编辑:程序博客网 时间:2024/06/05 23:43

netty入门小程序

server

public class TestNettyServer {    public static void main(String[] args) {        int port = 8888 ;        try {            new TestNettyServer().bind(port);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    private  void bind( int port) throws InterruptedException {        //reactor线程组        //用于服务端接受客户端连接        EventLoopGroup boosGroup=new NioEventLoopGroup();        //进行socketChannel 读写        EventLoopGroup workGroup=new NioEventLoopGroup();        try {            // netty 服务端启动类            ServerBootstrap serverBootstrap=new ServerBootstrap();            serverBootstrap.group(boosGroup, workGroup)                    //创建服务端                    .channel(NioServerSocketChannel.class)                    //设置tcp参数                    .option(ChannelOption.SO_BACKLOG, 1024)                    //处理io事件                    .childHandler(new ChannelInitializer<SocketChannel>() {                        @Override                        protected void initChannel(SocketChannel socketChannel) throws Exception {                            socketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter() {                                @Override                                public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {                                    //super.channelRead(ctx, msg);                                    ByteBuf buf = (ByteBuf)msg;                                    // 创建域buf中可读字节数相同大小的数组                                    byte[] req=new byte[buf.readableBytes()];                                    //将缓冲区可读字节复制到req数组中                                    buf.readBytes(req);                                    System.out.println(" the time server receiver request :" + new String(req, "utf-8"));                                    ByteBuf resp=Unpooled.copiedBuffer(new Date(System.currentTimeMillis()).toLocaleString().getBytes());                                    //写回客户端                                    ctx.write(resp);                                }                                @Override                                public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {                                    //super.channelReadComplete(ctx);                                    //刷新到缓冲数组中                                    ctx.flush();                                }                                @Override                                public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {                                    super.exceptionCaught(ctx, cause);                                    ctx.close();                                }                            });                        }                    });            //绑定端口,同步等待            ChannelFuture future = serverBootstrap.bind(port).sync();            future.channel().closeFuture().sync();        }finally {            //释放线程池资源            boosGroup.shutdownGracefully();            workGroup.shutdownGracefully();        }    }}//输出//the time server receiver request : tell me the time 

client

public class TestNettyClient {    public static void main(String[] args) throws InterruptedException {        //客户端工作线程组        EventLoopGroup clienGroup=new NioEventLoopGroup();        //客户端netty服务启动        Bootstrap bootstrap=new Bootstrap();        try {            bootstrap.group(clienGroup)                    //客户端通道                    .channel(NioSocketChannel.class)                    //设置可选参数                    .option(ChannelOption.TCP_NODELAY, true)                    //处理io事件                    .handler(new ChannelInitializer<SocketChannel>() {                        @Override                        protected void initChannel(SocketChannel socketChannel) throws Exception {                            socketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter() {                                @Override                                public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {                                    //super.channelRead(ctx, msg);                                    ByteBuf buf=(ByteBuf) msg;                                    // 创建域buf中可读字节数相同大小的数组                                    byte[] req=new byte[buf.readableBytes()];                                    //将缓冲区可读字节复制到req数组中                                    buf.readBytes(req);                                    System.out.println(" client receive resp from server that the time is  :" + new String(req, "utf-8"));                                }                                @Override                                public void channelActive(ChannelHandlerContext ctx) throws Exception {                                    super.channelActive(ctx);                                    //发送请求                                    byte[] bytes=" tell me the time ".getBytes();                                    ByteBuf buf=Unpooled.buffer(bytes.length);                                    buf.writeBytes(bytes);                                    ctx.writeAndFlush(buf);                                }                                @Override                                public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {                                    super.exceptionCaught(ctx, cause);                                    ctx.close();  //异常关闭资源                                }                            });                        }                    });            ChannelFuture future=bootstrap.connect("127.0.0.1", 8888).sync();            future.channel().closeFuture().sync();        }finally {            clienGroup.shutdownGracefully();        }    }}//输出//client receive resp from server that the time is  :2017-7-21 0:23:54

Tcp粘包/拆包

    tcp在传输数据时,可能会拆分为多个包进行发送,也可能会将多个小包合并为一个大包发送。    解决:    1.消息定长发送;    2.在包尾增加回车换车符进行分割    3.将消息分为消息头和消息体,消息头中包含表示消息总长度的字段。

server

public class TestTcpServer {    public static void main(String[] args) {        int port=8888;        try {            new TestTcpServer().bind(port);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    private void bind(int port) throws InterruptedException {        //reactor线程组        //用于服务端接受客户端连接        EventLoopGroup boosGroup=new NioEventLoopGroup();        //进行socketChannel 读写        EventLoopGroup workGroup=new NioEventLoopGroup();        //记录客户端请求次数        AtomicInteger atomicInteger=new AtomicInteger(0);        try {            // netty 服务端启动类            ServerBootstrap serverBootstrap=new ServerBootstrap();            serverBootstrap.group(boosGroup, workGroup)                    //创建服务端                    .channel(NioServerSocketChannel.class)                    //设置tcp参数                    .option(ChannelOption.SO_BACKLOG, 1024)                    //处理io事件                    .childHandler(new ChannelInitializer<SocketChannel>() {                        @Override                        protected void initChannel(SocketChannel socketChannel) throws Exception {                            //换行解码器                            socketChannel.pipeline(). addLast(new LineBasedFrameDecoder(1024));                            //直接将接受对象转化为String类型                            socketChannel.pipeline().addLast(new StringDecoder());                            //增加处理器                            socketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter() {                                @Override                                public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {                                    ////super.channelRead(ctx, msg);                                    //ByteBuf buf=(ByteBuf) msg;                                    //// 创建域buf中可读字节数相同大小的数组                                    //byte[] req=new byte[buf.readableBytes()];                                    ////将缓冲区可读字节复制到req数组中                                    //buf.readBytes(req);                                    String req = (String)msg ;                                    System.out.println(" the time server receiver request :"                                            + req                                            +" ; the count = " +  atomicInteger.incrementAndGet() );                                    String response=new Date(System.currentTimeMillis()).toLocaleString() + System.getProperty("line.separator");                                    ByteBuf resp=Unpooled.copiedBuffer(response.getBytes());                                    //写回客户端                                    ctx.write(resp);                                }                                @Override                                public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {                                    //super.channelReadComplete(ctx);                                    //刷新到缓冲数组中                                    ctx.flush();                                }                                @Override                                public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {                                    super.exceptionCaught(ctx, cause);                                    ctx.close();                                }                            });                        }                    });            //绑定端口,同步等待            ChannelFuture future=serverBootstrap.bind(port).sync();            future.channel().closeFuture().sync();        } finally {            //释放线程池资源            boosGroup.shutdownGracefully();            workGroup.shutdownGracefully();        }    }}//输出... the time server receiver request : tell me the time  ; the count = 99 the time server receiver request : tell me the time  ; the count = 100

client

public class TestTcpServer {    public static void main(String[] args) {        int port=8888;        try {            new TestTcpServer().bind(port);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    private void bind(int port) throws InterruptedException {        //reactor线程组        //用于服务端接受客户端连接        EventLoopGroup boosGroup=new NioEventLoopGroup();        //进行socketChannel 读写        EventLoopGroup workGroup=new NioEventLoopGroup();        //记录客户端请求次数        AtomicInteger atomicInteger=new AtomicInteger(0);        try {            // netty 服务端启动类            ServerBootstrap serverBootstrap=new ServerBootstrap();            serverBootstrap.group(boosGroup, workGroup)                    //创建服务端                    .channel(NioServerSocketChannel.class)                    //设置tcp参数                    .option(ChannelOption.SO_BACKLOG, 1024)                    //处理io事件                    .childHandler(new ChannelInitializer<SocketChannel>() {                        @Override                        protected void initChannel(SocketChannel socketChannel) throws Exception {                            //换行解码器                            socketChannel.pipeline(). addLast(new LineBasedFrameDecoder(1024));                            //直接将接受对象转化为String类型                            socketChannel.pipeline().addLast(new StringDecoder());                            //增加处理器                            socketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter() {                                @Override                                public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {                                    ////super.channelRead(ctx, msg);                                    //ByteBuf buf=(ByteBuf) msg;                                    //// 创建域buf中可读字节数相同大小的数组                                    //byte[] req=new byte[buf.readableBytes()];                                    ////将缓冲区可读字节复制到req数组中                                    //buf.readBytes(req);                                    String req = (String)msg ;                                    System.out.println(" the time server receiver request :"                                            + req                                            +" ; the count = " +  atomicInteger.incrementAndGet() );                                    String response=new Date(System.currentTimeMillis()).toLocaleString() + System.getProperty("line.separator");                                    ByteBuf resp=Unpooled.copiedBuffer(response.getBytes());                                    //写回客户端                                    ctx.write(resp);                                }                                @Override                                public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {                                    //super.channelReadComplete(ctx);                                    //刷新到缓冲数组中                                    ctx.flush();                                }                                @Override                                public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {                                    super.exceptionCaught(ctx, cause);                                    ctx.close();                                }                            });                        }                    });            //绑定端口,同步等待            ChannelFuture future=serverBootstrap.bind(port).sync();            future.channel().closeFuture().sync();        } finally {            //释放线程池资源            boosGroup.shutdownGracefully();            workGroup.shutdownGracefully();        }    }}//输出client receive resp from server that the time is  :2017-7-21 15:47:33 ; count  = 98 client receive resp from server that the time is  :2017-7-21 15:47:33 ; count  = 99      client receive resp from server that the time is  :2017-7-21 15:47:33 ; count  = 100
原创粉丝点击