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(ChannelHandlerContext ctx, ChannelStateEvent e){
ChannelBuffer buffer=(ChannelBuffer)e.getMessage();
int size=buffer.readableBytes();
byte[] bytes=new byte[size];
buffer.readBytes(bytes);
buffer.clear();
System.out.println(new String(bytes));//if the data size>1024,the String will speprate into parts.
}
}
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:
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,println() would execute twice
ChannelBuffer buffer = (ChannelBuffer) event.getMessage();
System.out.println(buffer) //buffer'size once 1024,once the remainder size
byte[] datas =buffer.readBytes(buffer.readableBytes()).array()
String msg=new String(datas , "UTF-8"); //BAD IDEA because the bytes sequence of the last UTF-8 char could be uncompleted there
System.out.println(str);
This is not the way to do that, you should instead use directly the StringEncoder and StringDecoder in the package org.jboss.netty.handler.codec.string. It will handle the Framing problem for you. If you still want to debug your code, use the LoggingHandler provided by Netty. Also did you really set this option:
bootstrap.setOption("tcpNoDelay", true);
in both sides bootstraps?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With