【问题标题】:Netty ChannelRead methodNetty ChannelRead 方法
【发布时间】:2014-12-20 07:58:08
【问题描述】:

我是使用 Netty 框架的新手。遇到一个问题,我用Netty写ServerSocket。 服务器的目标是从硬件接收消息。硬件每次发送一个字节。服务器和硬件有一个协议——每条消息都以“#”开头,以“*”结尾。

@Sharable
class ServerHandler extends ChannelInboundHandlerAdapter {
   @Override
   public void channelRead(ChannelHandlerContext ctx, Object msg) {
       BytBuf in = (ByteBuf) msg;
       CharBuffer charBuffer = CharBuffer.allocate(100);
       String recedata ;
       byte tmp;
       try {
           while (in.isReadable()) {
             tmp = in.readByte();
             if (tmp != 42) {    
                charBuffer.append((char) tmp);
               // System.out.println(String.valueOf(charBuffer.array()));
             } else {              //means receive a byte '*'
                charBuffer.append('*');
                count = 0; 
                recData = String.valueOf(charBuffer.array());
                logger.debug("receive message is " + recData);
             } 
       }catch(Exception e){
             e.printStackTrace();
       }

   }     
}

但是,出现了问题。当硬件第一次发送#abcd时,服务器将存储#abcd 然后硬件可能会发送efg*。由于Netty是异步的和事件驱动的,方法ChannelRead()会从头到尾运行。所以会打印efg*,而不是#abcdefg*

我想了很多。最后,我有一个想法。我使用AttribueKey 就像ThreadLocal 绑定一个数组以存储所有接收到的字节与通道。然后我从数组中得到#.....*。但数组会很大。这不是一个好方法。 你有更好的方法来解决我的问题吗?谢谢你的帮助

【问题讨论】:

    标签: netty serversocket channel


    【解决方案1】:

    查看 Netty 用户指南 - 处理基于流的传输。消息可能会变得支离破碎 - 因此在您的情况下,它可能会收到“#abcd”后跟“efg*”。由于您每次都分配一个 CharBuffer,因此原始 CharBuffer 包含“#abcd”。在第二个方法调用中,CharBuffer 包含“efg*”。

    解决方案是使用 ByteToMessageDecoder。 decode() 将被重复调用(由 Netty 框架),直到 ByteBuf 为空(即,您的解码代码清空它)。因此,您可以在 decode() 中执行的操作是不断返回,直到“in”ByteBuf 包含 * 字符。完成后,将 ByteBuf 的内容写入“out”列表,从开头的 # 到 *. * 之后的任何剩余字节都将留在 ByteBuf 中,并且该过程将继续。

    【讨论】:

    • 这对我很有帮助。我用你的方法,但是解码器不能是@sharable,那么在客户端很多的情况下如何使用服务器
    • 服务器为每个客户端连接创建一个通道。您需要为每个通道创建一个新的处理程序实例(或多个实例),否则同一处理程序将用于多个线程,在这种情况下,处理程序需要是线程安全的 - 这需要同步和 @Shareable(如果可以避免,则不推荐)开销和增加的复杂性和潜在的锁争用问题)。
    • 感谢您的帮助!现在,我更了解 Netty
    • 太好了,如果您认为已回答,介意将问题标记为已回答吗?
    猜你喜欢
    • 2015-11-19
    • 2014-02-15
    • 2016-02-02
    • 2019-09-23
    • 2015-09-28
    • 1970-01-01
    • 2018-12-05
    • 2021-01-28
    • 2021-07-24
    相关资源
    最近更新 更多