Netty :Unpooled.copiedBuffer 以块的形式向客户端发送长字符串消息

Netty :Unpooled.copiedBuffer sending messages to client in chunks for long string messages

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

这就是我之前发送消息的方式,它能够将消息作为单个消息发送(使用 wrappedBuffer 而不是 copiedBuffer )。但是我希望我的消息针对大于 128 的字符串字符进行编码,因此我想使用 CharsetUtil 在 UTF_16 中进行编码,但这会破坏消息 vm_packaged = 新字符串(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();
        }
}

这就是 TCP 的工作原理...这里没有 "message boundaries" 的概念。通常你会做的是在你的字节序列前面加上一些长度字段,然后使用这个长度字段在另一个远程对等端重新组装序列。

请参阅 LengthFieldBasedFrameDecoder(对于接收方)和 LengthFieldPrepender 对于发送方。