I am using Netty for TCP server and TCP client application. I am writing messages to client by using Unpooled.copiedBuffer(myMsg.getByte() , CharsetUtil_UTF_16) . The problem is for string messages that are very large . Client recieves messages in chunks and not as a single message.
This is how I am sending the message earlier which was able to send message as a single message (using wrappedBuffer instead of copiedBuffer ). But I want my messages to be encoded for string characters that are bigger than 128 , hence i wanted to use CharsetUtil to encode in UTF_16 , but that is breaking messages vm_packaged = new String(b); ByteBuf resp1 = Unpooled.wrappedBuffer(vm_packaged.getBytes());
ctx.write(resp1); ctx.flush();
Below is my server code
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();
}
}
This is just how TCP works... There is no concept of "message boundaries" here. Usually what you would do is to prefix your byte sequence with some length field and then use this length field to reassembly the sequence on the other remote peer.
See LengthFieldBasedFrameDecoder
(for the receiving side) and LengthFieldPrepender
for the sending side.