netty 多线程传输518大小数据 出现数据错乱问题

薛泽群 发布于 2015/05/17 10:30
阅读 400
收藏 0

@davinking 你好,想跟你请教个问题:

小弟最近做项目遇到一个问题,就是netty开发程序,客户端发送0518xxxx(后面518个数据),然后发送给服务端,服务端的解码器是自己写的,大概意思就是读取长度,再根据长度去截取,不够长度时累计到下次读取,我发现这个方法单线程没有问题,多线程或出现数据错乱的问题呢,请问大家这个问题要怎么解决。以下是我服务端的解码器:

public class MsgDecoder extends FrameDecoder {

@Override
 protected Object decode(ChannelHandlerContext ctx, Channel channel,
   ChannelBuffer buf) throws Exception {

 
  if (buf.readableBytes() < 4) {
   return null;
  }
  buf.markReaderIndex();
  byte[] headBytes = new byte[4];
  buf.readBytes(headBytes);
  String lenStr = new String(headBytes, "gbk");
  int length = Integer.parseInt(lenStr);
  if (length < 4 || length > maxFrameLength) {
   throw new RuntimeException("Bad message length: " + length);
  }
  if (buf.readableBytes() < length) {
   buf.resetReaderIndex();
   System.out.println("长度不够");
   return null;
  }

  ChannelBuffer frame = buf.readBytes(length);
  String msgStr = frame.toString(Charset.forName("gbk"));
  //System.out.println("decoder:"+msgStr);
  return msgStr;
 
 }

 }

 

加载中
0
hibegin
hibegin

感觉和线程没有关系! 本质上没有好处理数据粘包。 直接用 int toString 这个不科学。0000-9999的数字。 后面readByte(99) 这样就可以返回对应长度的数据了吗? buf.readableBytes()<length+4

手机端不能使用 < 符号呀,。后面的内容都被替换掉了

薛泽群
薛泽群
回复 @wzfz : 有问题的吧 我换成每次都new一个就好了。
hibegin
hibegin
回复 @薛泽群 : 共用一个时没有问题的,比如servlet的单例多线程
薛泽群
薛泽群
我发现问题了,其实是我的服务端new的一个decoler只new了一次,意思就是所有的线程都共享了一个decoler,必须为每一个线程new一个decoder。 ChannelPipeline p = Channels.pipeline(); p.addLast("frameDecoder", new MsgDecoder(charset, 65540));
0
公孙二狗
公孙二狗

方法单线程没有问题,多线程或出现数据错乱的问题

加个 synchronized 不让并发访问试试

薛泽群
薛泽群
我也用过,但是会发现有些数据接收不到,好奇怪,不知道为什么。
0
davinking
davinking
在你这个解码器之前在增加一个 new LengthFieldBasedFrameDecoder 这个解码器 这样就可以解决掉你的问题 这个就是处理粘包和分包的
薛泽群
薛泽群
恩 我试过可以,但是客户端那边必须要先发一个长度,再发报文过来? 有解码器可以直接发送报文,报文里面有长度+报文内容,有这样的解码器吗?
0
davinking
davinking
这个解码器需要你自己来写,多长的内容,解码出什么对象 要根据自己的设计来实现
返回顶部
顶部