码迷,mamicode.com
首页 > Web开发 > 详细

netty之粘包分包的处理

时间:2017-12-15 15:03:35      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:工厂   row   ann   tin   ret   数据   err   adb   ace   

  1、netty在进行字节数组传输的时候,会出现粘包和分包的情况。当个数据还好,如果数据量很大。并且不间断的发送给服务器,这个时候就会出现粘包和分包的情况。

  2、简单来说:channelBuffer在接收包的时候,会在当时进行处理,但是当数据量一大,这个时候数据的分隔就不是很明显了。这个时候会出现数据多了或者少了的情况

  3、处理的方式,一般就是编解码。自己定义数据:数据长度+数据。这种简单的方式来实现。在server进行解密操作。

  4、具体的实现过程

  a、客户端进行编码

package com.troy.application.buffer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class Client {

    public static void main(String[] args) {
        try {
            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.connect(new InetSocketAddress("localhost",9000));
            //需要发送的数据
            String message = "hello";
            //这里的4代表message的长度所占字节
            ByteBuffer byteBuffer = ByteBuffer.allocate(4+message.length());
            //设置数据
            byteBuffer.putInt(message.length());
            byteBuffer.put(message.getBytes());
            //写出数据
            socketChannel.write(ByteBuffer.wrap(byteBuffer.array()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  b、服务端

package com.troy.application.buffer;

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 java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {

    public static void main(String[] args) {

        //声明服务类
        ServerBootstrap serverBootstrap = new ServerBootstrap();

        //设定线程池
        ExecutorService boss = Executors.newCachedThreadPool();
        ExecutorService work = Executors.newCachedThreadPool();

        //设置工厂
        serverBootstrap.setFactory(new NioServerSocketChannelFactory(boss,work));

        //设置管道流
        serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            @Override
            public ChannelPipeline getPipeline() throws Exception {
                ChannelPipeline channelPipeline = Channels.pipeline();
                //添加处理方式
                channelPipeline.addLast("decode",new PackageDecoder());
                channelPipeline.addLast("hello",new HelloHandler());
                return channelPipeline;
            }
        });
        //设置端口
        serverBootstrap.bind(new InetSocketAddress(9000));
    }
}

  c、解码

package com.troy.application.buffer;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;

public class PackageDecoder extends OneToOneDecoder {

    @Override
    protected Object decode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception {
        ChannelBuffer channelBuffer = (ChannelBuffer) o;
        if (channelBuffer.readableBytes() > 4) {
            //标记读取位置
            channelBuffer.markReaderIndex();
            //读取数据长度
            int n = channelBuffer.readInt();
            if (channelBuffer.readableBytes() < n) {
                //如果数据长度小于设定的数据,则处于缓存状态
                channelBuffer.resetReaderIndex();
                //缓存当前数据,等待数据接入
                return null;
            }
            byte[] bytes = new byte[n];
            channelBuffer.readBytes(bytes);
            return new String(bytes);
        }
        //缓存当前数据,等待数据接入
        return null;
    }
}

  d、数据接收处理

package com.troy.application.buffer;

import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;

public class HelloHandler extends SimpleChannelHandler{

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {

        System.out.println(e.getMessage());
    }
}

 

netty之粘包分包的处理

标签:工厂   row   ann   tin   ret   数据   err   adb   ace   

原文地址:http://www.cnblogs.com/ll409546297/p/8042802.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!