Alex Rivera | Logout

in netty, we can only write and receive data less than 1024bytes: how we can write or receive more?

Asked 2012-04-16T08:05:28.383
8

When writing 2048bytes in on handler, the messageRevieved method should be called twice to receive the all data... how I can receive the 2048bytes data in

Code

Server:

public class Server{
    public static void main(String[] args){
        ChannelFactory factory=new NioServerSocketChannelFactory(
            Executors.newCachedThreadPool(),
            Executors.newCachedThreadPool());
        ServerBootstrap bootstrap=new ServerBootstrap(factory);
        bootstrap.setPipelineFactory(new CarPipelineFactory());

        bootstrap.setOption("child.tcpNoDelay", true);
        bootstrap.setOption("child.keepAlive", true);

        bootstrap.bind(new InetSocketAddress(8989));
    }
}

Server Handler:

public class ServerHandler extends SimpleChannelHandler{

    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e){
        byte[] resp=data.getBytes();//data is a String greater than 1024bytes;
        ChannelBuffer buffer=ChannelBuffers.buffer(resp.length);
        buffer.writerBytes(resp);
        e.getChannel().write(buffer);
        buffer.clear();
    }
}

Client:

public class Client{
    public static void main(String[] args){
        ChannelFactory channelFactory=new NioClientSocketChannelFactory(
            Executors.newCachedThreadPool(),
            Executors.newCachedThreadPool());
        ClientBootstrap bootstrap=new ClientBootstrap(channelFactory);
        bootstrap.getPipeline().addLast("handler", new PhoneClientHandler());

        bootstrap.setOption("child.tcpNoDelay", true);
        bootstrap.setOption("child.keepAlive", true);

        bootstrap.connect(new InetSocketAddress("127.0.0.1",8181));
    }
}

Client Handler:

public class ClientHandler extends SimpleChannelHandler{
    public void messageRecieved(Chann
Edit
Report

1 Answer

6

Well you can always decide how many bytes to write at a time, but you definitely never know when and how many bytes are received (this is why NIO makes sense). You need to handle you own buffer for receiving a fix number of bytes you want. To do so you can use a FrameDecoder which is design for this purpose.

Additionaly, you can make sure the datas does not stay too long in the sender socket buffer by setting tcpNoDelay to true, so it will no wait for the current "frame" to reach a certain critical size before physically sending the datas.

If I understand well, you are writing let's say 2048 Bytes in one hand but all the datas are not received in the messagedReceived event on the other hand? Try to check these common issues:

  • you application terminates too early and the datas are not yet arrived
  • your datas are stucked in the socket buffer of the "sender" because you did not close the Channel and tcpNoDelay option was not set to true. This is causing the socket to wait for some additional bytes before sending the packet.
  • you did not read all the datas inside the ChannelBuffer but for a reason the readerIndex as been set to a further position

Try to show us some part of your code, it should make things easier...

ADDED 17/04/2012

If I understand you are trying to pass a byte array coding for a String from the sender to the receiver. Here is your code after a littel refactor:

----------------------------code ----------------------------write hand: response.size()>1024bytes

byte[] datas = ((String)msg).getBytes("UTF-8"); //ALWAYS SPECIFY THE ENCODING
ChannelBuffer buffer = ChannelBuffers.wrap(datas); //USE DIRECTLY THE ARRAY
System.out.println(buffer);    //buffer'size>1024 here
channel.write(buffer);

----------------------------recieve hand: should recieve twice,

answered 2012-04-16T12:30:12.263

Your Answer