예제 #1
0
        private void Check(byte[] data)
        {
            int index = 0;
            var conv  = ConverHelper.GetU32(data, index);
            Tuple <Queue <KCPPackage>, KCP> item = null;

            lock (SessionDic)
            {
                if (!SessionDic.TryGetValue(conv, out item))
                {
                    item = new Tuple <Queue <KCPPackage>, KCP>(new Queue <KCPPackage>(), new KCP(conv));
                    //如果会话中不存在conv则认为这是新连接,创建KCP状态机
                    SessionDic.Add(conv, item);
                    new Thread(Update)
                    {
                        IsBackground = true
                    }.Start(item);
                }
            }

            while (index < data.Length)
            {
                var tempItem = KCPPackage.Parse(data, index);
                if (tempItem.Item2 == 0)
                {
                    break;
                }
                index += tempItem.Item2;
                item.Item1.Enqueue(tempItem.Item1);
            }
        }
예제 #2
0
        private KCPPackage CreateSendPack(int size, byte frg)
        {
            var result = new KCPPackage();

            result.Data   = new byte[size];
            result.Length = (uint)size;
            result.Frg    = frg;
            return(result);
        }
예제 #3
0
        public int SendMsg(byte[] data)
        {
            if (data == null || data.Length == 0)
            {
                return(-1);
            }
            int count = 1;

            if (data.Length > mss)
            {
                count = (data.Length + mss - 1) / mss;
            }
            if (count > 255)
            {
                return(-2);
            }
            if (send_queue.Length > Max)
            {
                return(-3);
            }
            int offset = 0;

            for (int i = 0; i < count; i++)
            {
                KCPPackage pack = null;
                if (count - 1 == i)
                {
                    pack = CreateSendPack(data.Length - offset, 0);
                    Array.Copy(data, offset, pack.Data, 0, pack.Data.Length);
                    send_queue = append <KCPPackage>(send_queue, pack);
                    break;
                }
                pack = CreateSendPack(mss, (byte)(count - i - 1));
                Array.Copy(data, offset, pack.Data, 0, pack.Data.Length);
                send_queue = append <KCPPackage>(send_queue, pack);
                offset    += mss;
            }
            return(0);
        }
예제 #4
0
        public static Tuple <KCPPackage, int> Parse(byte[] data, int index)
        {
            if (data.Length - index < 24)
            {
                return(defaultval);
            }
            var pack = new KCPPackage();

            pack.Conv   = ConverHelper.GetU32(data, index);
            pack.Cmd    = ConverHelper.GetU8(data, index + 4);
            pack.Frg    = ConverHelper.GetU8(data, index + 5);
            pack.Wnd    = ConverHelper.GetU16(data, index + 6);
            pack.Ts     = ConverHelper.GetU16(data, index + 8);
            pack.Sn     = ConverHelper.GetU16(data, index + 12);
            pack.Una    = ConverHelper.GetU16(data, index + 16);
            pack.Length = ConverHelper.GetU16(data, index + 20);
            if ((data.Length - index - headlength) < pack.Length)
            {
                return(defaultval);
            }
            pack.Data = data.Skip(index + headlength).Take((int)pack.Length).ToArray();
            return(new Tuple <KCPPackage, int>(pack, (int)pack.Length + headlength));
        }
예제 #5
0
        public int input(KCPPackage data)
        {
            if (data.Conv != this._conv)
            {
                return(-1);
            }
            if (data.Cmd < 81 || data.Cmd > 84)
            {
                return(-2);
            }
            remoteRecvWnd = data.Wnd;
            int needAckedCount = 0;

            for (int i = 0; i < this.send_buf.Length; i++)
            {
                if (data.Una > send_buf[i].Sn)
                {
                    needAckedCount++;
                }
                else
                {
                    break;
                }
            }
            if (needAckedCount > 0)
            {
                this.send_buf = slice <KCPPackage>(this.send_buf, needAckedCount, this.send_buf.Length);
            }
            if (data.Cmd == 82)//ack
            {
                if (this.send_buf.Length > 0)
                {
                    if (this.send_buf[0].Sn <= data.Sn)
                    {
                        int index = 0;
                        foreach (var pack in this.send_buf)
                        {
                            if (pack.Sn == data.Sn)
                            {
                                this.send_buf = append <KCPPackage>(slice <KCPPackage>(this.send_buf, 0, index), slice <KCPPackage>(this.send_buf, index + 1, send_buf.Length));
                                break;
                            }
                            else
                            {
                                pack.fastack++;
                            }
                            index++;
                        }
                    }
                }
            }
            if (data.Cmd == 81)//push
            {
                if (this.rcv_next + this.rcv_wnd > data.Sn)
                {
                    //添加到待回执列表
                    append <Tuple <UInt32, UInt32> >(this.acklist, new Tuple <UInt32, UInt32>(data.Sn, ))
                    bool exist = false;
                    int topper = -1;
                    if (this.rcv_next <= data.Sn)
                    {
                        for (int i = 0; i < this.recv_buff.Length; i++)
                        {
                            var pack = this.recv_buff[i];
                            if (pack.Sn == data.Sn)
                            {
                                exist = true;
                                break;
                            }
                            if (data.Sn > pack.Sn)
                            {
                                topper = i;
                                break;
                            }
                        }
                    }
                    if (!exist)
                    {
                        if (topper == -1)
                        {
                            recv_buff = append <KCPPackage>(recv_buff, data);
                        }
                        else
                        {
                            recv_buff = append <KCPPackage>(slice <KCPPackage>(recv_buff, 0, topper), append <KCPPackage>(new KCPPackage[] { data }, slice <KCPPackage>(recv_buff, topper + 1, recv_buff.Length)));
                        }
                    }
                    int removecount = 0;
                    foreach (var pack in this.recv_buff)
                    {
                        if (this.rcv_next == pack.Sn)
                        {
                            this.recv_queue = append <KCPPackage>(this.recv_queue, pack);
                            this.rcv_next++;
                            removecount++;
                        }
                    }
                    if (removecount > 0)
                    {
                        this.recv_buff = slice <KCPPackage>(this.recv_buff, removecount, this.recv_buff.Length);
                    }
                }
            }
            if (data.Cmd == 83)
            {
                //todo wnd ask
            }
            if (data.Cmd == 84)
            {
            }
            return(0);
        }