开发者社区> 问答> 正文

netty多线程通信一次传输较大数据遇到的问题:报错

您好,刚入门netty,想请教大神们几个问题,对于只有一个线程一次传输过大的数据,通过这个方法解决了:传输时头4个字节保存数据大小,后面保存内容,接收时如果发现读取的数据长度不够,则累积到下一次读取,最后得到的message则为需要的数据。部分代码如下:
发送消息:
public static void sendMsg(ChannelHandlerContext ctx,byte[] bytes){
        ByteBuf buf = ctx.alloc().buffer();
        buf.writeInt(bytes.length);
        buf.writeBytes(bytes);
        ctx.writeAndFlush(buf);
    }
接收消息:
public class Decoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List<Object> out) throws Exception {
        if (buf.readableBytes()<buf.getInt(buf.readerIndex())){
            return;
        }
        out.add(buf.readBytes(buf.readableBytes()));
    }
}
现在我有个情景是,在传输数据时是多线程的,同一个时间会多次调用ctx.writeAndFlush方法发送数据(多线程使用的是同一个ctx对象),每次发送的数据也是比较大的数据,在接收的时候,是否会出现数据混乱的情况(一次传输数据过大,会多次调用decode方法,多线程环境下是否会出现问题?),我开50个线程测试时发现if (buf.readableBytes()<buf.getInt(buf.readerIndex()))这句代码报数组越位的异常,请问有什么好的解决办法吗,感谢!

展开
收起
kun坤 2020-06-06 17:02:03 779 0
1 条回答
写回答
取消 提交回答
  • netty中有多个线程,每个socketChannel唯一属于其中一个线程,因为用了一些轮询分配线程算法。

    这样的话,对于某一个socketChannel及其里面的ctx,只会有一个线程处理啊。

    如果在某个socketChannel的事件里对其它socket进行操作就比较麻烦了。

    ######本身一个线程发送的数据太大时server端会分多次来接收,若同一时间多个线程往同一个ctx对象里writeAndFlush数据,server端接受时也会分多次来接受,这样就不好再把数据给还原了吧######

    buf.getInt 会移动readIndex指针,如果数据不够会导致下一次包解析失败,所以需要先mark,在return之前再reset, 大概的代码应该是这个样子


    while(buf.readableBytes() >= 4) {
    	buf.markReaderIndex();
    	int length = buf.readInt();
    	if(buf.readableBytes() >= length) {
    		byte[] data = new byte[length];
    		buf.readBytes(data);
    		out.add(data);
    	} else {
    		buf.resetReaderIndex();
    		break;
    	}
    }







    ######

    你配合LengthFieldBasedFrameDecoder 可以轻松解决

    2020-06-06 17:02:07
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
多IO线程优化版 立即下载
基于大数据的全球电商系统性能优化 立即下载
开源大数据生态下 高性能分布式文件系统 立即下载