Esempio n. 1
0
        //User to KCP
        public void Send(byte[] data)
        {
            var pack = new KCPPacket()
            {
                data = data,
            };

            sendQueue.Enqueue(pack);
        }
Esempio n. 2
0
        //UDP to KCP
        public void Input(byte[] data, int length)
        {
            var pack = new KCPPacket();

            pack.DecodeData(data, length);
            lock (recvQueue)
            {
                recvQueue.Enqueue(pack);
            }
        }
Esempio n. 3
0
        private void HandleRecv()
        {
            var c = 0;

            while (c <= maxRecvNum)
            {
                KCPPacket recPack = null;
                lock (recvQueue)
                {
                    //服务器接收到客户端的ACK
                    if (recvQueue.Count > 0)
                    {
                        recPack = recvQueue.Dequeue();
                    }
                }

                if (recPack != null)
                {
                    c++;
                    var seg = recPack;
                    if (seg.isAck)
                    {
                        foreach (var s in sendBuf)
                        {
                            if (s.sn == seg.sn)
                            {
                                s.cmd = KCPPacketCMD.CMD_ACKED;
                                break;
                            }
                        }
                    }
                    else                      //只发送一次ACK给服务器 失败则服务器自己报文重发
                    //服务器发送的新的报文 只接受服务器区间内的报文
                    //拒绝服务器重复的报文winStart = 0 winEnd = 2
                    //如果处理过了则不再处理
                    //服务器和每个客户端有独立的连接和独立的序号顺序
                    //连接建立的时刻就是 0 2 确定了
                    {
                        var srvSn = seg.sn;
                        var ret   = CheckInWin(srvSn, ackWinStart, ackWinEnd);

                        //窗口边界的怎么处理不知道是否已经验证过了两倍大小的接受窗口
                        //sendSize 2  ackSz = 4
                        if (ret)
                        {
                            var sendACK = new KCPPacket();
                            sendACK.isAck = true;
                            sendACK.sn    = seg.sn;
                            sendACK.EncodeFull();
                            //sendQueue.Enqueue(sendACK);
                            outputFunc(sendACK);                            //立即发送ACK

                            var tailHalfST  = ackWinStart + windSz;
                            var tailHalfEND = ackWinEnd;
                            //数据出现在后半端,则可以移动接受窗口了
                            if (CheckInWin(srvSn, tailHalfST, tailHalfEND))
                            {
                                ackWinStart++;
                                ackWinEnd++;
                                ackYet.Remove(ackWinStart - 1);
                                recvList.MoveStart();
                                Console.WriteLine("WinSz:" + ackWinStart + ":" + ackWinEnd);
                            }

                            if (!ackYet.Contains(srvSn))
                            {
                                ackYet.Add(srvSn);
                                //recvBuf.Enqueue(seg);

                                recvList.AddPacket(seg, srvSn - ackWinStart);
                                CheckLoopList();
                                Console.WriteLine("Ack:" + srvSn);
                            }
                        }
                    }
                }
                else
                {
                    break;
                }
            }
        }
Esempio n. 4
0
        //将新来的报文放到某个slot上面
        public void AddPacket(KCPPacket pack, UInt32 index)
        {
            var id = (start + index) % (total);

            recvSlots[(int)id] = pack;
        }