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

oOjackOo 发布于 2015/04/02 10:53
阅读 5K+
收藏 0
您好,刚入门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()))这句代码报数组越位的异常,请问有什么好的解决办法吗,感谢!
加载中
0
强子大叔的码田
强子大叔的码田

netty中有多个线程,每个socketChannel唯一属于其中一个线程,因为用了一些轮询分配线程算法。

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

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

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

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;
	}
}







0
davinking
davinking

你配合LengthFieldBasedFrameDecoder 可以轻松解决

返回顶部
顶部