Exemplo n.º 1
0
 private byte[] kcpRead()
 {
     while (udpClient != null)
     {
         var size = mKCP.PeekSize();
         if (size > 0)
         {
             lock (mKCP)
             {
                 if (size > mRecvBuffer.Length)
                 {
                     mRecvBuffer = new byte[(size * 3) / 2];
                 }
                 var n         = mKCP.Recv(mRecvBuffer, 0, size);
                 var recvBytes = (((int)mRecvBuffer[0]) << 8) + mRecvBuffer[1];
                 if (recvBytes <= n - 2)
                 {
                     byte[] data = new byte[recvBytes];
                     Array.Copy(mRecvBuffer, Const.PackageHeaderLength, data, 0, recvBytes);
                     return(data);
                 }
             }
         }
         var reclen = rawRead();
         int inputN = 0;
         lock (mKCP)
         {
             int sidx = 0;
             while (sidx < reclen)
             {
                 uint datalen = 0;
                 KCP.ikcp_decode32u(sRecvBuffer, sidx + 20, ref datalen);
                 int kcplen = (int)datalen + 24;
                 if (redlen <= 0 || sRecvBuffer[4 + sidx] != KCP.IKCP_CMD_PUSH)
                 {
                     inputN = mKCP.Input(sRecvBuffer, sidx, kcplen, true, ackNoDelay);
                 }
                 else
                 {
                     int pnum = redRevFmt(sRecvBuffer, sidx, kcplen);
                     for (int i = 0; i < pnum; i++)
                     {
                         uint tDataLen = 0;
                         KCP.ikcp_decode32u(redBuffer[i], 20, ref tDataLen);
                         inputN = mKCP.Input(redBuffer[i], 0, (int)tDataLen + 24, true, ackNoDelay);
                     }
                 }
                 sidx += kcplen;
             }
         }
         if (inputN < 0)
         {
             DebugLogger.Debug($"input err resinput {inputN}");
         }
     }
     return(null);
 }
Exemplo n.º 2
0
        // 处理接收冗余
        private int redRevFmt(byte[] data, int offset, int kcplen)
        {
            int    pnum = 0;
            int    pDataLen = 0;
            UInt32 sn = 0, csn;

            KCP.ikcp_decode32u(data, offset + 12, ref sn);
            int rIndex = 24 + offset;

            if (data[rIndex] == 0xff)
            {
                rIndex += 1;
            }
            for (UInt32 i = 0; i < (redlen + 1); i++)
            {
                if (i == 0 && (data[24 + offset] != 0xff || data[offset + 5] > 0))
                {
                    pDataLen = kcplen - rIndex + offset;
                }
                else
                {
                    pDataLen = (((int)data[rIndex]) << 8) + data[rIndex + 1] + 2;
                }
                csn = sn - i;
                // 验证是否已被接收,第一个包只记录不做验证
                if (i >= 1)
                {
                    if (csn < minredidx)
                    {
                        break;
                    }
                    if (chkBitmap(csn))
                    {
                        continue;
                    }
                    if (pDataLen <= 2)
                    {
                        continue;
                    }
                }
                if (redBuffer[i].Length < 24 + pDataLen)
                {
                    redBuffer[i] = new byte[24 + pDataLen];
                }
                Array.Copy(data, offset, redBuffer[i], 0, 24);
                Array.Copy(data, rIndex, redBuffer[i], 24, pDataLen);
                // 修改包数据
                KCP.ikcp_encode32u(redBuffer[i], 12, csn);
                KCP.ikcp_encode32u(redBuffer[i], 20, (uint)pDataLen);
                rIndex += pDataLen;
                pnum++;
                setBitmap(csn, true);
                if (minredidx == csn)
                {
                    while (chkBitmap(minredidx))
                    {
                        // 设置为1
                        setBitmap(minredidx, false);
                        // 检查下一个是否提交,提交继续往前累加
                        minredidx++;
                    }
                }
                if (rIndex >= kcplen + offset)
                {
                    break;
                }
            }
            return(pnum);
        }