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); }
// 处理接收冗余 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); }