gpt4 book ai didi

netty - 在netty中,我们只能写入和接收小于1024bytes的数据 : how we can write or receive more?

转载 作者:行者123 更新时间:2023-12-04 06:07:06 24 4
gpt4 key购买 nike

在处理程序中写入 2048bytes 时,应调用两次 messageRevieved 方法以接收所有数据......我如何接收 2048bytes 数据

代码

服务器:

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));
}
}

服务器处理程序:
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();
}
}

客户:
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));
}
}

客户端处理程序:
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.
}
}

最佳答案

好吧,您总是可以决定一次写入多少字节,但您绝对不知道何时以及接收了多少字节(这就是 NIO 有意义的原因)。您需要处理自己的缓冲区以接收所需的固定字节数。为此,您可以使用 帧解码器 这是为此目的而设计的。

另外,您可以通过设置 来确保数据不会在发送方套接字缓冲区中停留太久。 tcpNoDelay 为真,因此在物理发送数据之前,它不会等待当前“帧”达到某个临界大小。

如果我理解得很好,你正在写让我们一方面说 2048 字节,但另一方面没有在 messagedReceived 事件中收到所有数据?
尝试检查这些常见问题:

  • 您的应用程序终止得太早,数据尚未到达
  • 您的数据被卡在“发件人”的套接字缓冲区中,因为您没有 关闭 channel 和 tcpNoDelay 选项未设置为 true。这导致套接字在发送数据包之前等待一些额外的字节。
  • 您没有读取 ChannelBuffer 中的所有数据,但出于某种原因 读者索引如被设置到更远的位置

  • 尝试向我们展示您的代码的某些部分,它应该会使事情变得更容易...

    添加于 17/04/2012

    如果我了解您正在尝试将字符串的字节数组编码从发送方传递给接收方。这是小重构后的代码:

    - - - - - - - - - - - - - - 代码 - - - - - - - - - - - -------写手: 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);

    ---------------------------- 收到手:应该收到两次,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);

    这不是这样做的方法,您应该直接使用 字符串编码器 字符串解码器 包裹内 org.jboss.netty.handler.codec.string .它将为您处理框架问题。
    如果您仍想调试代码,请使用 LoggingHandler 由 Netty 提供。
    您是否真的设置了此选项:
    bootstrap.setOption("tcpNoDelay", true);

    在双方引导?

    关于netty - 在netty中,我们只能写入和接收小于1024bytes的数据 : how we can write or receive more?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10170564/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com