Netty实现SSL双向验证完整实例

 一、证书准备

     要使用ssl双向验证,就必须先要生成服务端和客户端的证书,并相互添加信任,具体流程如下(本人调试这个用例的时候,花了很多时间来验证证书是否正确,以及握手失败的原因,这里证书生成过程只要按流程走,本人能保证绝对没有问题)

现在打开cmd,在哪个目录下打开,证书就会放在哪个目录下:

第一步:   生成Netty服务端私钥和证书仓库命令

 keytool -genkey -alias securechat -keysize 2048 -validity 365 -keyalg RSA -dname "CN=localhost" -keypass sNetty -storepass sNetty -keystore sChat.jks

  • -keysize 2048 密钥长度2048位(这个长度的密钥目前可认为无法被暴力破解)
  • -validity 365 证书有效期365天
  • -keyalg RSA 使用RSA非对称加密算法
  • -dname "CN=localhost" 设置Common Name为localhost
  • -keypass sNetty密钥的访问密码为sNetty
  • -storepass sNetty密钥库的访问密码为sNetty(其实这两个密码也可以设置一样,通常都设置一样,方便记)
  • -keystore sChat.jks 指定生成的密钥库文件为sChata.jks

第二步:生成Netty服务端自签名证书

             keytool -export -alias securechat -keystore sChat.jks -storepass sNetty -file sChat.cer

 第三步:生成客户端的密钥对和证书仓库,用于将服务端的证书保存到客户端的授信证书仓库中

    keytool -genkey -alias smcc -keysize 2048 -validity 365  -keyalg RSA -dname "CN=localhost" -keypass sNetty  -storepass sNetty -keystore cChat.jks

第四步:将Netty服务端证书导入到客户端的证书仓库中

keytool -import -trustcacerts -alias securechat -file sChat.cer -storepass sNetty -keystore cChat.jks

如果你只做单向认证,则到此就可以结束了,如果是双响认证,则还需继续往下走

第五步:生成客户端自签名证书

  keytool -export -alias smcc -keystore cChat.jks -storepass sNetty -file cChat.cer

最后一步:将客户端的自签名证书导入到服务端的信任证书仓库中:

   keytool -import -trustcacerts -alias smcc -file cChat.cer -storepass sNetty -keystore sChat.jks

            

到这里,证书就生成完毕了,我们就可以得到两个jks文件,一个是服务端的sChat.jks  ,一个是客户端的cChat.jks   ,这两个文件后面初始化sslCOntext的时候会用到

如果还想了解更多可以查看

http://dwj147258.iteye.com/blog/2339934

二、netty服务端

       下面就直接贴代码了,首先是实例化SSLContext的类:

Java代码  收藏代码
  1. package main.java.com.nionetty;  
  2.   
  3. import java.io.FileInputStream;  
  4. import java.io.IOException;  
  5. import java.security.KeyStore;  
  6. import java.security.NoSuchAlgorithmException;  
  7.   
  8. import javax.net.ssl.KeyManager;  
  9. import javax.net.ssl.KeyManagerFactory;  
  10. import javax.net.ssl.SSLContext;  
  11. import javax.net.ssl.TrustManager;  
  12. import javax.net.ssl.TrustManagerFactory;  
  13.   
  14. import org.springframework.core.io.ClassPathResource;  
  15. /** 
  16.  * 初始化sslcontext类 
  17.  * 
  18.  */  
  19. public class ContextSSLFactory {  
  20.       
  21.     private static final SSLContext SSL_CONTEXT_S ;  
  22.       
  23.     private static final SSLContext SSL_CONTEXT_C ;  
  24.       
  25.     static{  
  26.         SSLContext sslContext = null ;  
  27.         SSLContext sslContext2 = null ;  
  28.         try {  
  29.             sslContext = SSLContext.getInstance("SSLv3") ;  
  30.             sslContext2 = SSLContext.getInstance("SSLv3") ;  
  31.         } catch (NoSuchAlgorithmException e1) {  
  32.             e1.printStackTrace();  
  33.         }  
  34.         try{  
  35.             if(getKeyManagersServer() != null && getTrustManagersServer() != null ){  
  36.                 sslContext.init(getKeyManagersServer(), getTrustManagersServer(), null);  
  37.             }  
  38.             if(getKeyManagersClient() != null && getTrustManagersClient() != null){  
  39.                 sslContext2.init(getKeyManagersClient(), getTrustManagersClient(), null);  
  40.             }  
  41.               
  42.         }catch(Exception e){  
  43.             e.printStackTrace() ;  
  44.         }  
  45.         sslContext.createSSLEngine().getSupportedCipherSuites() ;  
  46.         sslContext2.createSSLEngine().getSupportedCipherSuites() ;  
  47.         SSL_CONTEXT_S = sslContext ;   
  48.         SSL_CONTEXT_C = sslContext2 ;  
  49.     }  
  50.     public ContextSSLFactory(){  
  51.           
  52.     }  
  53.     public static SSLContext getSslContext(){  
  54.         return SSL_CONTEXT_S ;  
  55.     }  
  56.     public static SSLContext getSslContext2(){  
  57.         return SSL_CONTEXT_C ;  
  58.     }  
  59.     private static TrustManager[] getTrustManagersServer(){  
  60.         FileInputStream is = null ;  
  61.         KeyStore ks = null ;  
  62.         TrustManagerFactory keyFac = null ;  
  63.           
  64.         TrustManager[] kms = null ;  
  65.         try {  
  66.              // 获得KeyManagerFactory对象. 初始化位默认算法  
  67.             keyFac = TrustManagerFactory.getInstance("SunX509") ;  
  68.             is =new FileInputStream( (new ClassPathResource("main/java/conf/sChat.jks")).getFile() );  
  69.             ks = KeyStore.getInstance("JKS") ;  
  70.             String keyStorePass = "sNetty" ;  
  71.             ks.load(is , keyStorePass.toCharArray()) ;  
  72.             keyFac.init(ks) ;  
  73.             kms = keyFac.getTrustManagers() ;  
  74.         } catch (Exception e) {  
  75.             e.printStackTrace();  
  76.         }  
  77.         finally{  
  78.             if(is != null ){  
  79.                 try {  
  80.                     is.close() ;  
  81.                 } catch (IOException e) {  
  82.                     e.printStackTrace();  
  83.                 }  
  84.             }  
  85.         }  
  86.         return kms ;  
  87.     }  
  88.     private static TrustManager[] getTrustManagersClient(){  
  89.         FileInputStream is = null ;  
  90.         KeyStore ks = null ;  
  91.         TrustManagerFactory keyFac = null ;  
  92.           
  93.         TrustManager[] kms = null ;  
  94.         try {  
  95.              // 获得KeyManagerFactory对象. 初始化位默认算法  
  96.             keyFac = TrustManagerFactory.getInstance("SunX509") ;  
  97.             is =new FileInputStream( (new ClassPathResource("main/java/conf/cChat.jks")).getFile() );  
  98.             ks = KeyStore.getInstance("JKS") ;  
  99.             String keyStorePass = "sNetty" ;  
  100.             ks.load(is , keyStorePass.toCharArray()) ;  
  101.             keyFac.init(ks) ;  
  102.             kms = keyFac.getTrustManagers() ;  
  103.         } catch (Exception e) {  
  104.             e.printStackTrace();  
  105.         }  
  106.         finally{  
  107.             if(is != null ){  
  108.                 try {  
  109.                     is.close() ;  
  110.                 } catch (IOException e) {  
  111.                     e.printStackTrace();  
  112.                 }  
  113.             }  
  114.         }  
  115.         return kms ;  
  116.     }  
  117.     private static KeyManager[] getKeyManagersServer(){  
  118.         FileInputStream is = null ;  
  119.         KeyStore ks = null ;  
  120.         KeyManagerFactory keyFac = null ;  
  121.           
  122.         KeyManager[] kms = null ;  
  123.         try {  
  124.              // 获得KeyManagerFactory对象. 初始化位默认算法  
  125.             keyFac = KeyManagerFactory.getInstance("SunX509") ;  
  126.             is =new FileInputStream( (new ClassPathResource("main/java/conf/sChat.jks")).getFile() );  
  127.             ks = KeyStore.getInstance("JKS") ;  
  128.             String keyStorePass = "sNetty" ;  
  129.             ks.load(is , keyStorePass.toCharArray()) ;  
  130.             keyFac.init(ks, keyStorePass.toCharArray()) ;  
  131.             kms = keyFac.getKeyManagers() ;  
  132.         } catch (Exception e) {  
  133.             e.printStackTrace();  
  134.         }  
  135.         finally{  
  136.             if(is != null ){  
  137.                 try {  
  138.                     is.close() ;  
  139.                 } catch (IOException e) {  
  140.                     e.printStackTrace();  
  141.                 }  
  142.             }  
  143.         }  
  144.         return kms ;  
  145.     }  
  146.     private static KeyManager[] getKeyManagersClient(){  
  147.         FileInputStream is = null ;  
  148.         KeyStore ks = null ;  
  149.         KeyManagerFactory keyFac = null ;  
  150.           
  151.         KeyManager[] kms = null ;  
  152.         try {  
  153.              // 获得KeyManagerFactory对象. 初始化位默认算法  
  154.             keyFac = KeyManagerFactory.getInstance("SunX509") ;  
  155.             is =new FileInputStream( (new ClassPathResource("main/java/conf/cChat.jks")).getFile() );  
  156.             ks = KeyStore.getInstance("JKS") ;  
  157.             String keyStorePass = "sNetty" ;  
  158.             ks.load(is , keyStorePass.toCharArray()) ;  
  159.             keyFac.init(ks, keyStorePass.toCharArray()) ;  
  160.             kms = keyFac.getKeyManagers() ;  
  161.         } catch (Exception e) {  
  162.             e.printStackTrace();  
  163.         }  
  164.         finally{  
  165.             if(is != null ){  
  166.                 try {  
  167.                     is.close() ;  
  168.                 } catch (IOException e) {  
  169.                     e.printStackTrace();  
  170.                 }  
  171.             }  
  172.         }  
  173.         return kms ;  
  174.     }  
  175. }  

服务端启动类:

Java代码  收藏代码
  1. package main.java.com.nionetty;  
  2.   
  3. import javax.net.ssl.SSLEngine;  
  4. import javax.print.attribute.standard.MediaSize.Engineering;  
  5.   
  6. import main.java.com.nettyTest.SecureChatServerHandler;  
  7.   
  8. import io.netty.bootstrap.ServerBootstrap;  
  9. import io.netty.channel.ChannelHandlerContext;  
  10. import io.netty.channel.ChannelInitializer;  
  11. import io.netty.channel.ChannelOption;  
  12. import io.netty.channel.ChannelPipeline;  
  13. import io.netty.channel.EventLoopGroup;  
  14. import io.netty.channel.nio.NioEventLoopGroup;  
  15. import io.netty.channel.socket.SocketChannel;  
  16. import io.netty.channel.socket.nio.NioServerSocketChannel;  
  17. import io.netty.handler.logging.LogLevel;  
  18. import io.netty.handler.logging.LoggingHandler;  
  19. import io.netty.handler.ssl.SslHandler;  
  20. import io.netty.handler.timeout.IdleState;  
  21. import io.netty.handler.timeout.IdleStateEvent;  
  22. import io.netty.handler.timeout.IdleStateHandler;  
  23.   
  24. public class NettySocketServer {  
  25.     private static SslHandler sslHandler = null ;  
  26.       
  27.     private EventLoopGroup bossGroup = null ;  
  28.       
  29.     private EventLoopGroup workerGroup = null ;  
  30.       
  31.     public void start(){  
  32.         bossGroup = new NioEventLoopGroup() ;  
  33.         workerGroup = new NioEventLoopGroup() ;  
  34.         try{  
  35.             ServerBootstrap serverStrap = new ServerBootstrap() ;  
  36.             serverStrap.group(bossGroup , workerGroup)  
  37.             .channel(NioServerSocketChannel.class)  
  38.             .option(ChannelOption.SO_BACKLOG, 128)  
  39.             .option(ChannelOption.SO_KEEPALIVE, true)  
  40.             .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000 * 5 * 60)  
  41.             .handler(new LoggingHandler(LogLevel.DEBUG))  
  42.             .childHandler(new ChannelInitializer<SocketChannel>() {  
  43.   
  44.                 @Override  
  45.                 protected void initChannel(SocketChannel socketChannel) throws Exception {  
  46.                     ChannelPipeline pie = socketChannel.pipeline() ;  
  47.                     pie.addLast("decoder" , new MyDecoder()) ;  
  48.                     pie.addLast("encoder" , new MyEncoder()) ;  
  49.                     pie.addLast("handler" , new NettySocketSSLHandler()) ;  
  50.                     SSLEngine engine = ContextSSLFactory.getSslContext().createSSLEngine();  
  51.                     engine.setUseClientMode(false);  
  52.                     engine.setNeedClientAuth(true);  
  53.                     pie.addFirst("ssl", new SslHandler(engine));  
  54.                 }  
  55.                   
  56.             });  
  57.             serverStrap.bind(161616).sync() ;  
  58.             System.out.println("服务已开启");  
  59.         }catch(Exception e){  
  60.             e.printStackTrace() ;  
  61.             bossGroup.shutdownGracefully() ;  
  62.             workerGroup.shutdownGracefully() ;  
  63.         }  
  64.           
  65.     }  
  66.         private SslHandler getSslHandler(){  
  67.             if(sslHandler == null ){  
  68.                 SSLEngine sslEngine = ContextSSLFactory.getSslContext().createSSLEngine() ;  
  69.                 sslEngine.setUseClientMode(false) ;  
  70.                 //false为单向认证,true为双向认证  
  71.                 sslEngine.setNeedClientAuth(true) ;  
  72.                 sslHandler = new SslHandler(sslEngine);  
  73.             }  
  74.             return sslHandler ;  
  75.         }  
  76.         public static void main(String[] args) {  
  77.             new NettySocketServer().start() ;  
  78.         }  
  79.           
  80. }  

 编码器:

Java代码  收藏代码
  1. package main.java.com.nionetty;  
  2.   
  3. import io.netty.buffer.ByteBuf;  
  4. import io.netty.channel.ChannelHandlerContext;  
  5. import io.netty.handler.codec.MessageToByteEncoder;  
  6.   
  7. import java.nio.ByteBuffer;  
  8.   
  9. public class MyEncoder extends MessageToByteEncoder<ByteBuffer>{  
  10.   
  11.     @Override  
  12.     protected void encode(ChannelHandlerContext ctx, ByteBuffer message,  
  13.             ByteBuf out) throws Exception {  
  14.   
  15.         if(message==null){  
  16.             return;  
  17.         }     
  18.         if(message.hasArray()){  
  19.             byte[] msg =message.array();  
  20.             if(msg == null || msg.length <= 0){  
  21.                 return;  
  22.             }  
  23.             out.writeBytes(msg) ;  
  24.         }  
  25.     }  
  26.       
  27.   
  28.      
  29. }  

 解码器:

Java代码  收藏代码
  1. /* 
  2.  * Copyright (C) TD Tech<br> 
  3.  * All Rights Reserved.<br> 
  4.  *  
  5.  */  
  6. package main.java.com.nionetty;  
  7.   
  8. import io.netty.buffer.ByteBuf;  
  9. import io.netty.channel.ChannelHandlerContext;  
  10. import io.netty.handler.codec.ByteToMessageDecoder;  
  11.   
  12. import java.nio.ByteBuffer;  
  13. import java.util.List;  
  14.   
  15. /** 
  16.  * Create Date: 2014-11-4 下午02:42:21<br> 
  17.  * Create Author: lWX232692<br> 
  18.  * Description : 
  19.  */  
  20. public class MyDecoder extends ByteToMessageDecoder {  
  21.   
  22.   
  23.     @Override  
  24.     protected void decode(ChannelHandlerContext ctx, ByteBuf buffer,  
  25.             List<Object> out) throws Exception {  
  26.         //UnpooledUnsafeDirectByteBuf(ridx: 0, widx: 1, cap: 1024)  
  27.         if (buffer != null) {  
  28.             ByteBuffer msg = null;  
  29.             try {  
  30.                 if(buffer.readableBytes() > 0 ){  
  31.                     msg = ByteBuffer.allocate(buffer.readableBytes()) ;  
  32.                     byte[] bb = new byte[buffer.readableBytes()] ;  
  33.                     buffer.readBytes(bb) ;  
  34.                     msg.put(bb);  
  35.                     msg.flip();  
  36.                 }  
  37.             } catch (Exception e) {  
  38.                 e.printStackTrace();  
  39.                 msg = null ;  
  40.             }  
  41.             if (msg != null) {  
  42.                 out.add(msg);  
  43.             }  
  44.         }  
  45.     }  
  46.   
  47.   
  48. }  

业务实现类:

Java代码  收藏代码
  1. package main.java.com.nionetty;  
  2.   
  3. import io.netty.channel.Channel;  
  4. import io.netty.channel.ChannelHandlerContext;  
  5. import io.netty.channel.SimpleChannelInboundHandler;  
  6. import io.netty.handler.ssl.SslHandler;  
  7. import io.netty.util.concurrent.Future;  
  8. import io.netty.util.concurrent.GenericFutureListener;  
  9.   
  10. import java.net.InetAddress;  
  11. import java.nio.ByteBuffer;  
  12. import java.util.Arrays;  
  13.   
  14. public class NettySocketSSLHandler extends SimpleChannelInboundHandler<ByteBuffer>{  
  15.      @Override  
  16.         public void channelActive(final ChannelHandlerContext ctx) throws Exception {  
  17.             // Once session is secured, send a greeting and register the channel to the global channel  
  18.             // list so the channel received the messages from others.  
  19.             ctx.pipeline().get(SslHandler.class).handshakeFuture().addListener(  
  20.                     new GenericFutureListener<Future<Channel>>() {  
  21.                         @Override  
  22.                         public void operationComplete(Future<Channel> future) throws Exception {  
  23.                             if(future.isSuccess()){  
  24.                                 System.out.println("握手成功");  
  25.                                 byte[] array = new byte[]{ (byte)7d,  04} ;  
  26.                                 ByteBuffer bu = ByteBuffer.wrap(array) ;  
  27.                                 ctx.channel().writeAndFlush(bu) ;  
  28.                             }else{  
  29.                                 System.out.println("握手失败");  
  30.                             }  
  31.                             ctx.writeAndFlush(  
  32.                                     "Welcome to " + InetAddress.getLocalHost().getHostName() +  
  33.                                             " secure chat service! ");  
  34.                             ctx.writeAndFlush(  
  35.                                     "Your session is protected by " +  
  36.                                             ctx.pipeline().get(SslHandler.class).engine().getSession().getCipherSuite() +  
  37.                                             " cipher suite. ");  
  38.   
  39.                         }  
  40.                     });  
  41.         }  
  42.     @Override  
  43.     public void handlerAdded(ChannelHandlerContext ctx)  
  44.         throws Exception {  
  45.          System.out.println("服务端增加");  
  46.     }  
  47.       
  48.     @Override  
  49.     public void handlerRemoved(ChannelHandlerContext ctx){  
  50.         System.out.println("移除:"+ctx.channel().remoteAddress());  
  51.     }  
  52.     @Override  
  53.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {  
  54.        System.out.println("Unexpected exception from downstream.");  
  55.         ctx.close();  
  56.     }  
  57.     @Override  
  58.     public void messageReceived(ChannelHandlerContext ctx, ByteBuffer msg) throws Exception {  
  59.         System.out.println("服务端receive msg ");  
  60.         byte[] array = new byte[]{00, 01, 00, 00, 00, 06, 05, 03, (byte)7d, 00, 00, 07} ;  
  61.         ByteBuffer bu = ByteBuffer.wrap(array) ;  
  62.         ctx.channel().writeAndFlush(bu) ;  
  63.     }  
  64.       
  65. }  

三、客户端

     客户端实现类

Java代码  收藏代码
  1. package main.java.com.nionetty.client;  
  2.   
  3. import java.net.InetSocketAddress;  
  4. import java.net.SocketAddress;  
  5.   
  6. import javax.net.ssl.SSLEngine;  
  7.   
  8. import io.netty.bootstrap.Bootstrap;  
  9. import io.netty.channel.Channel;  
  10. import io.netty.channel.ChannelFuture;  
  11. import io.netty.channel.ChannelInitializer;  
  12. import io.netty.channel.ChannelOption;  
  13. import io.netty.channel.ChannelPipeline;  
  14. import io.netty.channel.EventLoopGroup;  
  15. import io.netty.channel.nio.NioEventLoopGroup;  
  16. import io.netty.channel.socket.SocketChannel;  
  17. import io.netty.channel.socket.nio.NioSocketChannel;  
  18. import io.netty.handler.ssl.SslHandler;  
  19. import main.java.com.nionetty.ContextSSLFactory;  
  20. import main.java.com.nionetty.MyDecoder;  
  21. import main.java.com.nionetty.MyEncoder;  
  22.   
  23. public class NettySocketClient {  
  24.       
  25.     private EventLoopGroup group ;  
  26.       
  27.     private Channel channel = null ;   
  28.     public void connect(String ip , int port){  
  29.         group = new NioEventLoopGroup();  
  30.         try{  
  31.             Bootstrap strap = new Bootstrap();  
  32.             strap.group(group)  
  33.             .channel(NioSocketChannel.class)  
  34.             .option(ChannelOption.TCP_NODELAY, true)  
  35.             .option(ChannelOption.SO_KEEPALIVE , true)  
  36.             .handler(new ChannelInitializer<SocketChannel>() {  
  37.                 @Override  
  38.                 protected void initChannel(SocketChannel socketChannel) throws Exception {  
  39.                     ChannelPipeline pieple = socketChannel.pipeline() ;  
  40.                     pieple.addLast("decoder" , new MyClientDecoder()) ;  
  41.                     pieple.addLast("encoder" , new MyClientEncoder()) ;  
  42.                     pieple.addLast("handler" , new NettySocketSSLClientHandler()) ;  
  43.                      SSLEngine engine = ContextSSLFactory.getSslContext2().createSSLEngine();  
  44.                      engine.setUseClientMode(true);  
  45.                      pieple.addFirst("ssl", new SslHandler(engine));  
  46.                 }  
  47.             });  
  48.         SocketAddress address = new InetSocketAddress(ip, port);  
  49.         final ChannelFuture future = strap.connect(address).sync();  
  50.         channel = future.awaitUninterruptibly().channel();  
  51.         System.out.println("连接成功, channel =" + channel.remoteAddress());  
  52.         }catch(Exception e ){  
  53.             e.printStackTrace();  
  54.             group.shutdownGracefully() ;  
  55.         }finally{  
  56.               
  57.         }  
  58.     }  
  59.     private static SslHandler sslHandlerClient = null ;  
  60.     public static SslHandler getSslHandler(){  
  61.         if(sslHandlerClient == null){  
  62.             SSLEngine sslEngine = ContextSSLFactory.getSslContext2().createSSLEngine() ;  
  63.             sslEngine.setUseClientMode(true) ;  
  64.             sslHandlerClient = new SslHandler(sslEngine);  
  65.         }  
  66.         return sslHandlerClient ;  
  67.     }  
  68.     public static void main(String[] args) {  
  69.         new NettySocketClient().connect("192.168.10.256", 161616) ;  
  70.     }  
  71. }  

 编码器:

Java代码  收藏代码
  1. package main.java.com.nionetty.client;  
  2.   
  3. import io.netty.buffer.ByteBuf;  
  4. import io.netty.channel.ChannelHandlerContext;  
  5. import io.netty.handler.codec.MessageToByteEncoder;  
  6.   
  7. import java.nio.ByteBuffer;  
  8.   
  9. public class MyClientEncoder extends MessageToByteEncoder<ByteBuffer>{  
  10.   
  11.     @Override  
  12.     protected void encode(ChannelHandlerContext ctx, ByteBuffer message,  
  13.             ByteBuf out) throws Exception {  
  14.   
  15.         if(message==null){  
  16.             return;  
  17.         }     
  18.         if(message .hasArray()){  
  19.             byte[] msg =message.array();  
  20.             if(msg == null || msg.length <= 0){  
  21.                 return;  
  22.             }  
  23.             out.writeBytes(msg);  
  24.         }  
  25.     }  
  26.       
  27.   
  28.      
  29. }  

 解码器:

Java代码  收藏代码
  1. /* 
  2.  * Copyright (C) TD Tech<br> 
  3.  * All Rights Reserved.<br> 
  4.  *  
  5.  */  
  6. package main.java.com.nionetty.client;  
  7.   
  8. import io.netty.buffer.ByteBuf;  
  9. import io.netty.channel.ChannelHandlerContext;  
  10. import io.netty.handler.codec.ByteToMessageDecoder;  
  11.   
  12. import java.nio.ByteBuffer;  
  13. import java.util.List;  
  14.   
  15. /** 
  16.  * Create Date: 2014-11-4 下午02:42:21<br> 
  17.  * Create Author: lWX232692<br> 
  18.  * Description : 
  19.  */  
  20. public class MyClientDecoder extends ByteToMessageDecoder {  
  21.   
  22.   
  23.     @Override  
  24.     protected void decode(ChannelHandlerContext ctx, ByteBuf buffer,  
  25.             List<Object> out) throws Exception {  
  26.         //UnpooledUnsafeDirectByteBuf(ridx: 0, widx: 1, cap: 1024)  
  27.         if (buffer != null) {  
  28.             ByteBuffer msg = null;  
  29.             try {  
  30.                 if(buffer.readableBytes() > 0 ){  
  31.                     msg = ByteBuffer.allocate(buffer.readableBytes()) ;  
  32.                     byte[] bb = new byte[buffer.readableBytes()] ;  
  33.                     buffer.readBytes(bb) ;  
  34.                     msg.put(bb);  
  35.                     msg.flip();  
  36.                 }  
  37.             } catch (Exception e) {  
  38.                 e.printStackTrace();  
  39.                 msg = null ;  
  40.             }  
  41.             if (msg != null) {  
  42.                 out.add(msg);  
  43.             }  
  44.         }  
  45.     }  
  46.   
  47.   
  48. }  

 业务handler:

Java代码  收藏代码
  1. /* 
  2.  * Copyright (C) TD Tech<br> 
  3.  * All Rights Reserved.<br> 
  4.  *  
  5.  */  
  6. package main.java.com.nionetty.client;  
  7.   
  8. import io.netty.buffer.ByteBuf;  
  9. import io.netty.channel.ChannelHandlerContext;  
  10. import io.netty.handler.codec.ByteToMessageDecoder;  
  11.   
  12. import java.nio.ByteBuffer;  
  13. import java.util.List;  
  14.   
  15. /** 
  16.  * Create Date: 2014-11-4 下午02:42:21<br> 
  17.  * Create Author: lWX232692<br> 
  18.  * Description : 
  19.  */  
  20. public class MyClientDecoder extends ByteToMessageDecoder {  
  21.   
  22.   
  23.     @Override  
  24.     protected void decode(ChannelHandlerContext ctx, ByteBuf buffer,  
  25.             List<Object> out) throws Exception {  
  26.         //UnpooledUnsafeDirectByteBuf(ridx: 0, widx: 1, cap: 1024)  
  27.         if (buffer != null) {  
  28.             ByteBuffer msg = null;  
  29.             try {  
  30.                 if(buffer.readableBytes() > 0 ){  
  31.                     msg = ByteBuffer.allocate(buffer.readableBytes()) ;  
  32.                     byte[] bb = new byte[buffer.readableBytes()] ;  
  33.                     buffer.readBytes(bb) ;  
  34.                     msg.put(bb);  
  35.                     msg.flip();  
  36.                 }  
  37.             } catch (Exception e) {  
  38.                 e.printStackTrace();  
  39.                 msg = null ;  
  40.             }  
  41.             if (msg != null) {  
  42.                 out.add(msg);  
  43.             }  
  44.         }  
  45.     }  
  46.   
  47.   
  48. }  

 测试通过,搞了因为在网上没有找到完整的实例,所以因为一个小问题,找了两天都没有找到原因,希望看到的同学能够有所收获

原文地址:https://www.cnblogs.com/developer-ios/p/11417730.html