• netty 拆包和粘包 (三)


    在tcp编程底层都有拆包和粘包的机制

      拆包

        当发送数据量过大时数据量会分多次发送

       以前面helloWord代码为例

        

    package com.liqiang.nettyTest2;
    
    public class nettyMain {
        public static void main(String[] args) {
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    Server server = new Server(8081);
                    server.start();
                }
            }).start();
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    Client client1=new Client("127.0.0.1", 8081);
                    client1.connection();
                    client1.sendMsg("In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. His book w"  
                            + "ill give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the process "  
                            + "of configuring and connecting all of Netty’s components to bring your learned about threading models in ge"  
                            + "neral and Netty’s threading model in particular, whose performance and consistency advantages we discuss"  
                            + "ed in detail In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. Hi"  
                            + "s book will give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the"  
                            + " process of configuring and connecting all of Netty’s components to bring your learned about threading "  
                            + "models in general and Netty’s threading model in particular, whose performance and consistency advantag"  
                            + "es we discussed in detailIn this chapter you general, we recommend Java Concurrency in Practice by Bri"  
                            + "an Goetz. His book will give We’ve reached an exciting point—in the next chapter;the counter is: 1 2222"  
                            + "sdsa ddasd asdsadas dsadasdas");
                }
            }).start();
        }
    }

    打印

    可以发现这里拆分成了2次发送

      粘包

        当发送数据量过小时会组合成一次发送

    package com.liqiang.nettyTest2;
    
    public class nettyMain {
        public static void main(String[] args) {
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    Server server = new Server(8081);
                    server.start();
                }
            }).start();
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    Client client1=new Client("127.0.0.1", 8081);
                    client1.connection();
                    for(int i=0;i<100;i++) {
                        client1.sendMsg("d");
                    }
                    
                    
                }
            }).start();
        }
    }

    可以发现有时多条发送的数据会组合成一条发送

    解决方案

    netty提供了解码器来解决拆包和粘包的问题

    LineBasedFrameDecoder 

    通过换行符来区分包

    服务器端增加LineBasedFrameDecoder

    package com.liqiang.nettyTest2;
    
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.handler.codec.LineBasedFrameDecoder;
    import io.netty.handler.codec.AsciiHeadersEncoder.NewlineType;
    import io.netty.handler.codec.string.StringDecoder;
    import io.netty.handler.codec.string.StringEncoder;
    
    public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
    
        private Server server;
        public ServerChannelInitializer(Server server) {
            this.server=server;
        }
        @Override
        protected void initChannel(SocketChannel channel) throws Exception {
            // TODO Auto-generated method stub
            channel.pipeline()
            .addLast(new LineBasedFrameDecoder(2048))//2048是限制一个包的最大字节数。如果超过将会报异常
            .addLast("decoder",new StringDecoder())//接收到数据 自动将将buffer转换为String 避免自己再转
            .addLast("encoder",new StringEncoder())//发送数据 可以直接发送String 框架内部转换为buffer传输
            .addLast(new ServerHandle(server));
        }
    
    }

    客户端

    package com.liqiang.nettyTest2;
    
    public class nettyMain {
        public static void main(String[] args) {
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    Server server = new Server(8081);
                    server.start();
    
                }
            }).start();
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    Client client1=new Client("127.0.0.1", 8081);
                    client1.connection();
                    client1.sendMsg("In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. His book w"  
                            + "ill give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the process "  
                            + "of configuring and connecting all of Netty’s components to bring your learned about threading models in ge"  
                            + "neral and Netty’s threading model in particular, whose performance and consistency advantages we discuss"  
                            + "ed in detail In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. Hi"  
                            + "s book will give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the"  
                            + " process of configuring and connecting all of Netty’s components to bring your learned about threading "  
                            + "models in general and Netty’s threading model in particular, whose performance and consistency advantag"  
                            + "es we discussed in detailIn this chapter you general, we recommend Java Concurrency in Practice by Bri"  
                            + "an Goetz. His book will give We’ve reached an exciting point—in the next chapter;the counter is: 1 2222"  
                            + "sdsa ddasd asdsadas dsadasdas"+System.getProperty("line.separator"));//System.getProperty("line.separator") 兼容linux和windows换行符的区别
                }
            }).start();
        }
    }

    如果发送数据忘记拼换行符 服务器将不会有任何打印

    DelimiterBasedFrameDecoder

    通过指定符号区分

    服务器端

    package com.liqiang.nettyTest2;
    
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.handler.codec.LineBasedFrameDecoder;
    import io.netty.handler.codec.AsciiHeadersEncoder.NewlineType;
    import io.netty.handler.codec.DelimiterBasedFrameDecoder;
    import io.netty.handler.codec.string.StringDecoder;
    import io.netty.handler.codec.string.StringEncoder;
    
    public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
    
        private Server server;
        public ServerChannelInitializer(Server server) {
            this.server=server;
        }
        @Override
        protected void initChannel(SocketChannel channel) throws Exception {
            // TODO Auto-generated method stub
            channel.pipeline()
            .addLast(new DelimiterBasedFrameDecoder(2048,Unpooled.copiedBuffer("$$__".getBytes())))//$__为包的分隔符2048是限制一个包的最大字节数。如果超过将会报异常
            .addLast("decoder",new StringDecoder())//接收到数据 自动将将buffer转换为String 避免自己再转
            .addLast("encoder",new StringEncoder())//发送数据 可以直接发送String 框架内部转换为buffer传输
            .addLast(new ServerHandle(server));
        }
    
    }

    客户端

    package com.liqiang.nettyTest2;
    
    public class nettyMain {
        public static void main(String[] args) {
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    Server server = new Server(8081);
                    server.start();
    
                }
            }).start();
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    Client client1=new Client("127.0.0.1", 8081);
                    client1.connection();
                    client1.sendMsg("In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. His book w"  
                            + "ill give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the process "  
                            + "of configuring and connecting all of Netty’s components to bring your learned about threading models in ge"  
                            + "neral and Netty’s threading model in $$__particular, whose performance and consistency advantages we discuss"  
                            + "ed in detail In this chapter you general, we recommend Java Concurrency in Practice by Brian Goetz. Hi"  
                            + "s book will give We’ve reached an exciting point—in the next chapter we’ll discuss bootstrapping, the"  
                            + " process of configuring and connecting all $$__of Netty’s components to bring your learned about threading "  
                            + "models in general and Netty’s threading model in particular, whose performance and consistency advantag"  
                            + "es we discussed in detailIn this chapter you general, we recommend Java Concurrency in Practice by Bri"  
                            + "an Goetz. His book will give We’ve reached an exciting point—in the next chapter;the counter is: 1 2222"  
                            + "sdsa ddasd asdsadas dsadasdas$__");
                }
            }).start();
        }
    }

    根据$__数据被拆分成了三个包

  • 相关阅读:
    快速复习正则表达式
    常用正则表达式
    用SqlConnectionStringBuilder修改连接超时时间
    GRUB 启动 WIN PE 镜像(ISO)
    win xp 关闭动画屏幕角色,那只小狗
    win xp firefox,chrome 在浏览网页时字体发虚,可以设置为新宋体
    OpenFileDialog 打开快捷方式时,返回的是快捷方式引用的路径,而不是快捷方式(.lnk)自身的路径
    关闭IE 对剪切板访问的提示
    svn 提交代码 自动过滤技巧,自动过滤不想提交的文件和文件夹
    WinForm 打开文件夹
  • 原文地址:https://www.cnblogs.com/LQBlog/p/9147759.html
Copyright © 2020-2023  润新知