public List <IByteBuffer> decode(FecPacket pkt) { if (pkt.Flag == Fec.typeParity) { Snmp.snmp.FECParityShards++; } else { Snmp.snmp.FECDataShards++; } int n = rx.Count - 1; int insertIdx = 0; for (int i = n; i >= 0; i--) { //去重 if (pkt.Seqid == rx[i].Seqid) { Snmp.snmp.FECRepeatDataShards++; pkt.release(); return(null); } if (pkt.Seqid > rx[i].Seqid) { // insertion insertIdx = i + 1; break; } } //插入 rx中 if (insertIdx == n + 1) { this.rx.Add(pkt); } else { rx.Insert(insertIdx, pkt); } //所有消息列表中的第一个包 // shard range for current packet long shardBegin = pkt.Seqid - pkt.Seqid % shardSize; long shardEnd = shardBegin + shardSize - 1; //rx数组中的第一个包 // max search range in ordered queue for current shard int searchBegin = (int)(insertIdx - pkt.Seqid % shardSize); if (searchBegin < 0) { searchBegin = 0; } int searchEnd = searchBegin + shardSize - 1; if (searchEnd >= rx.Count) { searchEnd = rx.Count - 1; } List <IByteBuffer> result = null; if (searchEnd - searchBegin + 1 >= dataShards) { //当前包组的已收到的包数量 int numshard = 0; //当前包组中属于数据包的数量 int numDataShard = 0; //搜到第一个包在搜索行中的位置 int first = 0; //收到的最大包的字节长度 int maxlen = 0; // zero cache IByteBuffer[] shards = decodeCache; bool[] shardsflag = flagCache; for (int i = 0; i < shards.Length; i++) { shards[i] = null; shardsflag[i] = false; } for (int i = searchBegin; i <= searchEnd; i++) { FecPacket fecPacket = rx[i]; long seqid = fecPacket.Seqid; if (seqid > shardEnd) { break; } if (seqid < shardBegin) { continue; } shards[(int)(seqid % shardSize)] = fecPacket.Data; shardsflag[(int)(seqid % shardSize)] = true; numshard++; if (fecPacket.Flag == Fec.typeData) { numDataShard++; } if (numshard == 1) { first = i; } if (fecPacket.Data.ReadableBytes > maxlen) { maxlen = fecPacket.Data.ReadableBytes; } } if (numDataShard == dataShards) { freeRange(first, numshard, rx); } else if (numshard >= dataShards) { for (int i = 0; i < shards.Length; i++) { IByteBuffer shard = shards[i]; //如果数据不存在 用0填充起来 if (shard == null) { shards[i] = zeros.Copy(0, maxlen); shards[i].SetWriterIndex(maxlen); continue; } int left = maxlen - shard.ReadableBytes; if (left > 0) { shard.WriteBytes(this.zeros, left); zeros.ResetReaderIndex(); // zeros.resetReaderIndex(); } } codec.decodeMissing(shards, shardsflag, 0, maxlen); result = new List <IByteBuffer>(this.dataShards); for (int i = 0; i < shardSize; i++) { if (shardsflag[i]) { continue; } IByteBuffer byteBufs = shards[i]; //释放构建的parityShards内存 if (i >= dataShards) { byteBufs.Release(); continue; } int packageSize = byteBufs.ReadShort(); if (byteBufs.ReadableBytes < packageSize) { //// System.out.println("bytebuf长度: " + byteBufs.writerIndex() + " 读出长度" + packageSize); // byte[] bytes = new byte[byteBufs.writerIndex()]; // byteBufs.getBytes(0, bytes); // for (byte aByte : // bytes) { // System.out.print("[" + aByte + "] "); // } Snmp.snmp.FECErrs++; } else { Snmp.snmp.FECRecovered++; } //去除fec头标记的消息体长度2字段 byteBufs = byteBufs.Slice(Fec.fecDataSize, packageSize); //int packageSize =byteBufs.readUnsignedShort(); //byteBufs = byteBufs.slice(0,packageSize); result.Add(byteBufs); Snmp.snmp.FECRecovered++; //int packageSize =byteBufs.getUnsignedShort(0); ////判断长度 //if(byteBufs.writerIndex()-Fec.fecHeaderSizePlus2>=packageSize&&packageSize>0) //{ // byteBufs = byteBufs.slice(Fec.fecHeaderSizePlus2,packageSize); // result.add(byteBufs); // Snmp.snmp.FECRecovered.incrementAndGet(); //}else{ // System.out.println("bytebuf长度: "+byteBufs.writerIndex()+" 读出长度"+packageSize); // byte[] bytes = new byte[byteBufs.writerIndex()]; // byteBufs.getBytes(0,bytes); // for (byte aByte : bytes) { // System.out.print("["+aByte+"] "); // } // Snmp.snmp.FECErrs.incrementAndGet(); //} } freeRange(first, numshard, rx); } } if (rx.Count > rxlimit) { if (rx[0].Flag == Fec.typeData) { Snmp.snmp.FECShortShards++; } freeRange(0, 1, rx); } return(result); }