【问题标题】:Netty :Unpooled.copiedBuffer sending messages to client in chunks for long string messagesNetty :Unpooled.copiedBuffer 为长字符串消息分块发送消息给客户端
【发布时间】:2019-08-19 14:17:45
【问题描述】:

我将 Netty 用于 TCP 服务器和 TCP 客户端应用程序。我正在使用 Unpooled.copiedBuffer(myMsg.getByte() , CharsetUtil_UTF_16) 向客户端写入消息。问题在于非常大的字符串消息。客户端以块的形式接收消息,而不是作为单个消息。

这就是我之前发送消息的方式,它能够将消息作为单个消息发送(使用 WrappedBuffer 而不是 copyBuffer )。但我希望我的消息被编码为大于 128 的字符串字符,因此我想使用 CharsetUtil 以 UTF_16 进行编码,但这会破坏消息 vm_packaged = new String(b); ByteBuf resp1 = Unpooled.wrappedBuffer(vm_packaged.getBytes());

ctx.write(resp1); ctx.flush();

下面是我的服务器代码

public void channelRead(ChannelHandlerContext ctx, Object msg) { 
        try {
            ByteBuf buf = (ByteBuf) msg;
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);

            String body = "";
            CoffeeSendAndReceiveUtil csar = new CoffeeSendAndReceiveUtil();

            body = csar.parseMessage(req);

            logger.info(new Date());

            String vm_message=null;
            String vm_message_final=null;
            MachineDispatcher vmd =  new MachineDispatcher();
            vm_message = vmd.getMachineString(body);


            JSONObject product_done = null;
            try{
                order = new JSONObject(body);
                p_resp = new JSONObject(vm_message);

                if(order.has(PayTmConstantUtil.order_no)){
                    order_id = order.getString(PayTmConstantUtil.order_no);
                }

                if(order.getString(MachineConstant.CMD).equalsIgnoreCase(MachineConstant.QRCODE)){

                    if(order.getString(MachineConstant.QR_TYPE).equalsIgnoreCase(MachineConstant.paytm)){
                        if(!p_resp.has(PayTmConstantUtil.ERROR)){
                            loop = true;
                        }
                        if(p_resp.has(PayTmConstantUtil.signature)){

                            paytm_checksum = p_resp.getString(PayTmConstantUtil.signature);
                        }

                        p_resp.remove(PayTmConstantUtil.signature);
                        vm_message_final = p_resp.toString();
                    }

                    else if(order.getString(MachineConstant.QR_TYPE).equalsIgnoreCase(MachineConstant.phonepe)){
                        vm_message_final = vm_message;
                        merchantId = p_resp.getJSONObject(PhonePeConstant.data).getString(PhonePeConstant.merchantId);
                        phonepe = true;

                    }

                }

                else if(order.getString(MachineConstant.CMD).equalsIgnoreCase(MachineConstant.PRODUCTDONE)){
                    product_done = new JSONObject(vm_message);

                    if(product_done.getString(MachineConstant.CMD).equalsIgnoreCase(MachineConstant.PRODUCTDONE_R)){
                        create_product = true;
                    }

                    vm_message_final = vm_message;
                }

                else{
                    vm_message_final = vm_message;
                }

            }
            catch(JSONException je){
                logger.error(je.getClass()+ " -- "+je.getMessage());
            }

            if(vm_message_final!=null){

                CoffeeSendAndReceiveUtil csr = new CoffeeSendAndReceiveUtil();
                byte[] b = csr.packageMsg(vm_message_final);
                vm_packaged = new String(b);
                ByteBuf resp1 = Unpooled.wrappedBuffer(vm_packaged.getBytes());

                ctx.write(resp1);
                ctx.flush();
            }
        }
        catch(Exception ex ){
            logger.info("Exception in Channel Read");
            logger.error(ex.getClass()+" -- "+ex.getMessage());
        }

        finally {
            //ctx.close();
        }
}

【问题讨论】:

    标签: character-encoding netty tcpclient tcpserver


    【解决方案1】:

    这就是 TCP 的工作原理……这里没有“消息边界”的概念。通常你会做的是在你的字节序列前面加上一些长度字段,然后使用这个长度字段在另一个远程对等点上重新组装序列。

    请参阅LengthFieldBasedFrameDecoder(用于接收端)和LengthFieldPrepender 用于发送端。

    【讨论】:

    • 如果我们使用 netty 服务器,是否必须有一个 netty 客户端,在我们的例子中,客户端开发人员来自不同的组织,我们不确定他们是否使用 netty 客户端。我在我的消息中添加长度字段作为前缀,我们知道我们正在通过客户端接收它的网络丢失信息。前缀字节未按应有的方式传递
    猜你喜欢
    • 2015-04-07
    • 2017-10-26
    • 2017-03-08
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多