Beispiel #1
0
 public Exception Connect()
 {
     udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
     udpClient.Bind(new IPEndPoint(IPAddress.Parse("0.0.0.0"), udpPort));
     recIEpoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), udpPort);
     sndIEpoint = new IPEndPoint(IPAddress.Parse(udpIp), udpPort);
     // 创建KCP实例
     session = (uint)(new Random(DateTime.Now.Millisecond).Next(1, Int32.MaxValue)) + 1;
     mKCP    = new KCP(session, rawSend);
     // 设置kcp模式
     // normal:  0, 40, 2, 1
     // fast:    0, 30, 2, 1
     // fast2:   1, 20, 2, 1
     // fast3:   1, 10, 2, 1
     mKCP.NoDelay(nodelay, interval, resend, nc);
     mKCP.SetStreamMode(streamMode);
     // 设置接收和发送窗大小, 默认都为128
     mKCP.WndSize(sndwnd, recwnd);
     // 设置冗余长度,默认不使用冗余
     if (redlen > 0)
     {
         redData = new List <byte> [redlen];
         Array.Clear(redData, 0, redlen);
         int maxdatalen = redlen + recwnd;
         int bitmaplen  = maxdatalen >> 3;
         if (maxdatalen > bitmaplen << 3)
         {
             bitmaplen++;
         }
         redbitmap = new byte[bitmaplen];
         // 初始化冗余数据buffer
         redBuffer = new byte[redlen + 1][];
         for (int i = 0; i < redlen + 1; i++)
         {
             redBuffer[i] = new byte[256];
         }
     }
     // 启动更新定时器
     if (writeDelay > 0)
     {
         updateTimer = new Timer(new TimerCallback(kcpUpdate), null, Timeout.Infinite, Timeout.Infinite);
     }
     protocolRun = true;
     return(null);
 }
Beispiel #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);
        }