• 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. }  

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

  • 相关阅读:
    pytest入门 及allure2报告生成
    java 常用集合list与Set、Map区别及适用场景总结
    通俗地解释脏读、不可重复读、幻读
    Serializable接口的意义和用法
    maven基础
    Class.forName()用法详解
    关于getClass(),Object.class,getClassLoader的理解
    maven(一) maven到底是个啥玩意~
    TCP/IP协议族体系结构:死也不能忘记的四个层
    HTML表单常用标签
  • 原文地址:https://www.cnblogs.com/developer-ios/p/11417730.html
Copyright © 2020-2023  润新知