zoukankan      html  css  js  c++  java
  • netty9---使用编码解码器

    客户端:

    package com.client;
    
    import java.net.InetSocketAddress;
    import java.util.Scanner;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import org.jboss.netty.bootstrap.ClientBootstrap;
    import org.jboss.netty.channel.Channel;
    import org.jboss.netty.channel.ChannelFuture;
    import org.jboss.netty.channel.ChannelPipeline;
    import org.jboss.netty.channel.ChannelPipelineFactory;
    import org.jboss.netty.channel.Channels;
    import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
    import com.cn.codc.RequestEncoder;
    import com.cn.codc.ResponseDecoder;
    import com.cn.model.Request;
    import com.cn.module.fuben.request.FightRequest;
    /**
     * netty客户端入门
     */
    public class Client {
    
        public static void main(String[] args) throws InterruptedException {
            
            //服务类
            ClientBootstrap bootstrap = new  ClientBootstrap();
            
            //线程池
            ExecutorService boss = Executors.newCachedThreadPool();
            ExecutorService worker = Executors.newCachedThreadPool();
            
            //socket工厂
            bootstrap.setFactory(new NioClientSocketChannelFactory(boss, worker));
            
            //管道工厂
            bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
                
                @Override
                public ChannelPipeline getPipeline() throws Exception {
                    ChannelPipeline pipeline = Channels.pipeline();
                    pipeline.addLast("decoder", new ResponseDecoder());//Response解码器
                    pipeline.addLast("encoder", new RequestEncoder());//Request编码器
                    pipeline.addLast("hiHandler", new HiHandler());//通过ResponseDecoder解码的是一个Response对象。
                    return pipeline;
                }
            });
            
            //连接服务端
            ChannelFuture connect = bootstrap.connect(new InetSocketAddress("127.0.0.1", 10101));
            Channel channel = connect.sync().getChannel();
            
            System.out.println("client start");
            
            Scanner scanner = new Scanner(System.in);
            while(true){
                System.out.println("请输入");
                int fubenId = Integer.parseInt(scanner.nextLine());
                int count = Integer.parseInt(scanner.nextLine());
                
                FightRequest fightRequest = new FightRequest();
                fightRequest.setFubenId(fubenId);
                fightRequest.setCount(count);
                
                Request request = new Request();
                request.setModule((short) 1);//请求第一个模块的
                request.setCmd((short) 1);
                request.setData(fightRequest.getBytes());//fightRequest是数据体data
                //发送请求
                channel.write(request);
            }
        }
    
    }
    package com.client;
    
    import org.jboss.netty.channel.ChannelHandlerContext;
    import org.jboss.netty.channel.ChannelStateEvent;
    import org.jboss.netty.channel.ExceptionEvent;
    import org.jboss.netty.channel.MessageEvent;
    import org.jboss.netty.channel.SimpleChannelHandler;
    
    import com.cn.model.Response;
    import com.cn.model.StateCode;
    import com.cn.module.fuben.request.FightRequest;
    import com.cn.module.fuben.response.FightResponse;
    /**
     * 消息接受处理类
     */
    public class HiHandler extends SimpleChannelHandler {
    
        /**
         * 接收消息
         */
        @Override
        public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
                Response message = (Response)e.getMessage();//解码出来的之后是Response对象,然后进行业务处理
    
                if(message.getModule() == 1){
                    
                    if(message.getCmd() == 1){
                        FightResponse fightResponse = new FightResponse();
                        fightResponse.readFromBytes(message.getData());
                        
                        System.out.println("gold:" + fightResponse.getGold());
                        
                    }else if(message.getCmd() == 2){
                        
                    }
                    
                }else if (message.getModule() == 1){
                    
                    
                }
        }
    
        /**
         * 捕获异常
         */
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
            System.out.println("exceptionCaught");
            super.exceptionCaught(ctx, e);
        }
    
        /**
         * 新连接
         */
        @Override
        public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
            System.out.println("channelConnected");
            super.channelConnected(ctx, e);
        }
    
        /**
         * 必须是链接已经建立,关闭通道的时候才会触发
         */
        @Override
        public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
            System.out.println("channelDisconnected");
            super.channelDisconnected(ctx, e);
        }
    
        /**
         * channel关闭的时候触发
         */
        @Override
        public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
            System.out.println("channelClosed");
            super.channelClosed(ctx, e);
        }
    }

    服务端:

    package com.server;
    
    import java.net.InetSocketAddress;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    import org.jboss.netty.bootstrap.ServerBootstrap;
    import org.jboss.netty.channel.ChannelPipeline;
    import org.jboss.netty.channel.ChannelPipelineFactory;
    import org.jboss.netty.channel.Channels;
    import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
    import org.jboss.netty.handler.codec.string.StringDecoder;
    import org.jboss.netty.handler.codec.string.StringEncoder;
    
    import com.cn.codc.RequestDecoder;
    import com.cn.codc.ResponseEncoder;
    /**
     * netty服务端入门
     */
    public class Server {
    
        public static void main(String[] args) {
    
            //服务类
            ServerBootstrap bootstrap = new ServerBootstrap();
            
            //boss线程监听端口,worker线程负责数据读写
            ExecutorService boss = Executors.newCachedThreadPool();
            ExecutorService worker = Executors.newCachedThreadPool();
            
            //设置niosocket工厂
            bootstrap.setFactory(new NioServerSocketChannelFactory(boss, worker));
            
            //设置管道的工厂
            bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
                
                @Override
                public ChannelPipeline getPipeline() throws Exception {
    
                    ChannelPipeline pipeline = Channels.pipeline();
                    pipeline.addLast("decoder", new RequestDecoder());//Request的解码器
                    pipeline.addLast("encoder", new ResponseEncoder());//Response的编码器
                    pipeline.addLast("helloHandler", new HelloHandler());
                    return pipeline;
                }
            });
            bootstrap.bind(new InetSocketAddress(10101));
            System.out.println("start!!!");
        }
    }
    package com.server;
    
    import org.jboss.netty.channel.ChannelHandlerContext;
    import org.jboss.netty.channel.ChannelStateEvent;
    import org.jboss.netty.channel.ExceptionEvent;
    import org.jboss.netty.channel.MessageEvent;
    import org.jboss.netty.channel.SimpleChannelHandler;
    
    import com.cn.model.Request;
    import com.cn.model.Response;
    import com.cn.model.StateCode;
    import com.cn.module.fuben.request.FightRequest;
    import com.cn.module.fuben.response.FightResponse;
    /**
     * 消息接受处理类
     */
    public class HelloHandler extends SimpleChannelHandler {
    
        /**
         * 接收消息
         */
        @Override
        public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
    
            Request message = (Request)e.getMessage();
            
            if(message.getModule() == 1){
                
                if(message.getCmd() == 1){
                    
                    FightRequest fightRequest = new FightRequest();
                    fightRequest.readFromBytes(message.getData());
                    
                    System.out.println("fubenId:" +fightRequest.getFubenId() + "   " + "count:" + fightRequest.getCount());
                    
                    //回写数据
                    FightResponse fightResponse = new FightResponse();
                    fightResponse.setGold(9999);
                    
                    Response response = new Response();
                    response.setModule((short) 1);
                    response.setCmd((short) 1);
                    response.setStateCode(StateCode.SUCCESS);
                    response.setData(fightResponse.getBytes());
                    ctx.getChannel().write(response);
                }else if(message.getCmd() == 2){
                }
            }else if (message.getModule() == 1){
            }
        }
    
        /**
         * 捕获异常
         */
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
            System.out.println("exceptionCaught");
            super.exceptionCaught(ctx, e);
        }
    
        /**
         * 新连接
         */
        @Override
        public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
            System.out.println("channelConnected");
            super.channelConnected(ctx, e);
        }
    
        /**
         * 必须是链接已经建立,关闭通道的时候才会触发
         */
        @Override
        public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
            System.out.println("channelDisconnected");
            super.channelDisconnected(ctx, e);
        }
    
        /**
         * channel关闭的时候触发
         */
        @Override
        public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
            System.out.println("channelClosed");
            super.channelClosed(ctx, e);
        }
    }

    网络传的是字节数据不是字符。

    Netty之自定义数据包协议:
    give me a coffee give me a tea (2条信息)

    give me a coffeegive me a tea 粘包现象(2条信息粘在一起)

    give me
    a coffeegive me a tea 分包现象(第一条消息分开了,第一条后部分又粘到了第二条消息)

    粘包和分包出现的原因是:没有一个稳定数据结构(没有确定一个请求传递哪些数据)

    分割符:
    give me a coffee|give me a tea|
    give me a coffee|
    give me a tea|

    长度 + 数据:
    16give me a coffee13give me a tea(读取16个就封装成一个请求,投递到业务层去)
    16give me a coffee
    13give me a tea

  • 相关阅读:
    SVN访问配置及常用操作
    SVN配置
    在Eclipse中创建maven项目
    Maven的基础之环境配置
    线程池理解
    JVM之类的生命周期
    JAVA代码编程规范
    Jquery实现div局部页面刷新中js渲染失效问题解决
    觅踪17
    第十四周进度
  • 原文地址:https://www.cnblogs.com/yaowen/p/9063061.html
Copyright © 2011-2022 走看看