简体   繁体   中英

How to read more than 1024 bytes to x bytes in Netty

I am new here. I have this issue with netty. Data is getting truncated when it exceeds 1024 bytes. this issue arose when i ported from norm io Socket to Netty, using io i can read any data of x bytes like this TheClient is a separate thread that handles socket connection that has been accepted

public class TheClient extends Thread{

    private DataInputStream dis;
    private DataOutputStream dos;

  public TheClient(Socket s,SocketHandler sockHandler,SocketHandlerListener sockListener){        

     try{
          //open the streams to read and write data
            dis= new DataInputStream(this.s.getInputStream());
            dos=new DataOutputStream(this.s.getOutputStream());

          //this is how i read the data of any x bytes in server
            int len = dis.readInt();
            if(len >0){
            byte[]buffer = new byte[len];
            dis.readFully(buffer,0,buffer.length);
            String output = new String(buffer,0,buffer.length);
            CLIENT_REQUEST +=output;
            }
            //System.out.println("what i read: "+CLIENT_REQUEST);
       }catch(Exception ex){
            ex.printStackTrace();   
     } 
   }
}

How do i read the same x bytes using netty without losing the data. I tried this

        public class NettyServer{

            public static void main(String []args){
               EventLoopGroup group = new NioEventLoopGroup();
                try{
                    ServerBootstrap serverBootstrap = new ServerBootstrap();
                    serverBootstrap.group(group);
                    serverBootstrap.channel(NioServerSocketChannel.class);//"localhost",
                    serverBootstrap.localAddress(new InetSocketAddress(Integer.valueOf(port)));
                    serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            //pipeline.addLast(new HelloServerHandler2());
                            pipeline.addLast(new ClientHandler());      
                          }
                         });
                         ChannelFuture channelFuture = serverBootstrap.bind().sync();
                         channelFuture.channel().closeFuture().sync();
                      } catch(Exception e){
                        e.printStackTrace();
                     } finally {
                        group.shutdownGracefully().sync();
                    }
                 }
              }
            }

and then i have ClientHandler class where the read happens and where the data is truncated

   public class ClientHandler extends ChannelInboundHandlerAdapter {

       public ClientHandler () {
            System.out.println("Preparing..."); 

       }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            ByteBuf inBuffer = (ByteBuf) msg;

            //supposed to read 100kb data or string   
            String received = inBuffer.toString(CharsetUtil.UTF_8);
            //but output has been truncated to 1kb or less
            System.out.println("Server received: " + received);

            ctx.write(Unpooled.copiedBuffer("Hello : " + received, CharsetUtil.UTF_8));
            System.out.println("done from server: " );
        }

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
                    .addListener(ChannelFutureListener.CLOSE);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    }

I have searched and searched SO but none worked for me. How do i really read my full data in chunk until it is complete while appending to a StringBuffer or somethng... Please, help me. I am learning Netty and i am relatively new to java. Thanks.

You will beed to write your own decoder that will buffer the data until you receive everything. This is usually done by extending ByteToMessageDecoder and only put the ByteBuf to the out once it is complete.

Something like:

class MyDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
        if (in.readBytes() < expectedBytes) {
            return;
        }
        YourMessage message = decodeFromByteBuf(in);
        out.add(message);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM