示例#1
0
        /**
         *
         * when you received a low level packet (eg. UDP packet), call it
         *
         * @param data
         * @return
         */
        public int Input(ByteBuf data)
        {
            int una_temp = snd_una;
            int flag = 0, maxack = 0;

            if (data == null || data.ReadableBytes() < IKCP_OVERHEAD)
            {
                return(-1);
            }
            while (true)
            {
                bool readed = false;
                int  ts;
                int  sn;
                int  len;
                int  una;
                int  conv_;
                int  wnd;
                byte cmd;
                byte frg;
                if (data.ReadableBytes() < IKCP_OVERHEAD)
                {
                    break;
                }
                conv_ = data.ReadInt();
                if (this.conv != conv_)
                {
                    return(-1);
                }
                cmd = data.ReadByte();
                frg = data.ReadByte();
                wnd = data.ReadShort();
                ts  = data.ReadInt();
                sn  = data.ReadInt();
                una = data.ReadInt();
                len = data.ReadInt();
                if (data.ReadableBytes() < len)
                {
                    return(-2);
                }
                switch ((int)cmd)
                {
                case IKCP_CMD_PUSH:
                case IKCP_CMD_ACK:
                case IKCP_CMD_WASK:
                case IKCP_CMD_WINS:
                    break;

                default:
                    return(-3);
                }
                rmt_wnd = wnd & 0x0000ffff;
                Parse_una(una);
                Shrink_buf();
                switch (cmd)
                {
                case IKCP_CMD_ACK:
                    if (_itimediff(current, ts) >= 0)
                    {
                        Update_ack(_itimediff(current, ts));
                    }
                    Parse_ack(sn);
                    Shrink_buf();
                    if (flag == 0)
                    {
                        flag   = 1;
                        maxack = sn;
                    }
                    else if (_itimediff(sn, maxack) > 0)
                    {
                        maxack = sn;
                    }
                    break;

                case IKCP_CMD_PUSH:
                    Console.WriteLine(sn);
                    if (_itimediff(sn, rcv_nxt + rcv_wnd) < 0)
                    {
                        Ack_push(sn, ts);
                        if (_itimediff(sn, rcv_nxt) >= 0)
                        {
                            Segment seg = new Segment(len);
                            seg.conv = conv_;
                            seg.cmd  = cmd;
                            seg.frg  = frg & 0x000000ff;
                            seg.wnd  = wnd;
                            seg.ts   = ts;
                            seg.sn   = sn;
                            seg.una  = una;
                            if (len > 0)
                            {
                                seg.data.WriteBytes(data, len);
                                readed = true;
                            }
                            Parse_data(seg);
                        }
                    }
                    break;

                case IKCP_CMD_WASK:
                    // ready to send back IKCP_CMD_WINS in Ikcp_flush
                    // tell remote my window size
                    probe |= IKCP_ASK_TELL;
                    break;

                case IKCP_CMD_WINS:
                    // do nothing
                    break;

                default:
                    return(-3);
                }
                if (!readed)
                {
                    data.SkipBytes(len);
                }
            }
            if (flag != 0)
            {
                Parse_fastack(maxack);
            }
            if (_itimediff(snd_una, una_temp) > 0)
            {
                if (this.cwnd < this.rmt_wnd)
                {
                    if (this.cwnd < this.ssthresh)
                    {
                        this.cwnd++;
                        this.incr += mss;
                    }
                    else
                    {
                        if (this.incr < mss)
                        {
                            this.incr = mss;
                        }
                        this.incr += (mss * mss) / this.incr + (mss / 16);
                        if ((this.cwnd + 1) * mss <= this.incr)
                        {
                            this.cwnd++;
                        }
                    }
                    if (this.cwnd > this.rmt_wnd)
                    {
                        this.cwnd = this.rmt_wnd;
                        this.incr = this.rmt_wnd * mss;
                    }
                }
            }
            return(0);
        }
示例#2
0
        /**
         *
         * when you received a low level packet (eg. UDP packet), call it
         *
         * @param data
         * @return
         */
        public int Input(ByteBuf data)
        {
            int s_una = snd_una;

            if (data == null || data.ReadableBytes() < IKCP_OVERHEAD)
            {
                return(-1);
            }
            int offset = 0;

            while (true)
            {
                int  ts;
                int  sn;
                int  length;
                int  una;
                int  conv_;
                int  wnd;
                byte cmd;
                byte frg;
                if (data.ReadableBytes() < IKCP_OVERHEAD)
                {
                    break;
                }
                conv_   = data.ReadInt();
                offset += 4;
                if (conv != conv_)
                {
                    return(-1);
                }
                cmd     = data.ReadByte();
                offset += 1;
                frg     = data.ReadByte();
                offset += 1;
                wnd     = data.ReadShort();
                offset += 2;
                ts      = data.ReadInt();
                offset += 4;
                sn      = data.ReadInt();
                offset += 4;
                una     = data.ReadInt();
                offset += 4;
                length  = data.ReadInt();
                offset += 4;
                if (data.ReadableBytes() < length)
                {
                    return(-2);
                }
                switch ((int)cmd)
                {
                case IKCP_CMD_PUSH:
                case IKCP_CMD_ACK:
                case IKCP_CMD_WASK:
                case IKCP_CMD_WINS:
                    break;

                default:
                    return(-3);
                }
                rmt_wnd = wnd & 0x0000ffff;
                parse_una(una);
                shrink_buf();
                switch (cmd)
                {
                case IKCP_CMD_ACK:
                    if (_itimediff(current, ts) >= 0)
                    {
                        update_ack(_itimediff(current, ts));
                    }
                    parse_ack(sn);
                    shrink_buf();
                    break;

                case IKCP_CMD_PUSH:
                    if (_itimediff(sn, rcv_nxt + rcv_wnd) < 0)
                    {
                        ack_push(sn, ts);
                        if (_itimediff(sn, rcv_nxt) >= 0)
                        {
                            Segment seg = new Segment(length);
                            seg.conv = conv_;
                            seg.cmd  = cmd;
                            seg.frg  = frg & 0x000000ff;
                            seg.wnd  = wnd;
                            seg.ts   = ts;
                            seg.sn   = sn;
                            seg.una  = una;
                            if (length > 0)
                            {
                                seg.data.WriteBytes(data, length);
                            }
                            parse_data(seg);
                        }
                    }
                    break;

                case IKCP_CMD_WASK:
                    // ready to send back IKCP_CMD_WINS in Ikcp_flush
                    // tell remote my window size
                    probe |= IKCP_ASK_TELL;
                    break;

                // do nothing
                case IKCP_CMD_WINS:
                    break;

                default:
                    return(-3);
                }
                offset += length;
            }
            if (_itimediff(snd_una, s_una) > 0)
            {
                if (cwnd < rmt_wnd)
                {
                    int mss_ = mss;
                    if (cwnd < ssthresh)
                    {
                        cwnd++;
                        incr += mss_;
                    }
                    else
                    {
                        if (incr < mss_)
                        {
                            incr = mss_;
                        }
                        incr += (mss_ * mss_) / incr + (mss_ / 16);
                        if ((cwnd + 1) * mss_ <= incr)
                        {
                            cwnd++;
                        }
                    }
                    if (cwnd > rmt_wnd)
                    {
                        cwnd = rmt_wnd;
                        incr = rmt_wnd * mss_;
                    }
                }
            }
            return(0);
        }