在处理程序中写入2048字节时,应该调用messageRevieved方法两次以接收所有数据...如何接收2048字节数据
码
服务器:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
服务器处理程序:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
客户:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
客户端处理程序:
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.
}
}
Run Code Online (Sandbox Code Playgroud)
那么你总是可以决定一次写入多少字节,但你绝对不知道接收的时间和字节数(这就是NIO有意义的原因).您需要处理自己的缓冲区以接收所需的固定字节数.为此,您可以使用为此目的而设计的FrameDecoder.
另外,通过将tcpNoDelay设置为true,可以确保数据在发送方套接字缓冲区中不会保持太长时间,因此在物理发送数据之前,它不会等待当前"帧"达到某个临界大小.
如果我理解得很好,你一方面写一下2048字节,但另一方面又没有在messagedReceived事件中收到所有数据?尝试检查这些常见问题:
试着向我们展示你的代码的一部分,它应该让事情变得更容易......
ADDED 17/04/2012
如果我理解你正在尝试将字符串数组编码从发送方传递给接收方.以下是小型重构后的代码:
---------------------------- code --------------------- -------写手: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);
Run Code Online (Sandbox Code Playgroud)
----------------------------收到手:应该收到两次,println()会执行两次
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);
Run Code Online (Sandbox Code Playgroud)
这不是这样做的方法,您应该直接使用包org.jboss.netty.handler.codec.string中的StringEncoder和StringDecoder.它将为您处理框架问题.如果您仍想调试代码,请使用Netty提供的LoggingHandler.你也真的设置了这个选项:
bootstrap.setOption("tcpNoDelay", true);
Run Code Online (Sandbox Code Playgroud)
在双方的bootstraps?
| 归档时间: |
|
| 查看次数: |
9325 次 |
| 最近记录: |