src/main/java/org/beykery/jkcp/Kcp.java
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) {
            boolean 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.readIntLE();
            if (this.conv != conv_) {
                return -1;
            }
            cmd = data.readByte();
            frg = data.readByte();
            wnd = data.readShortLE();
            ts = data.readIntLE();
            sn = data.readIntLE();
            una = data.readIntLE();
            len = data.readIntLE();
            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:
                    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;
    }
/**
     * when you received a low level packet (eg. UDP packet), call it
     *
     * @param data
     * @return
     */
when you received a low level packet , call it
@param data
@return
when you received a low level 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) {
            boolean 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.readIntLE();
            if (this.conv != conv_) {
                return -1;
            }
            cmd = data.readByte();
            frg = data.readByte();
            wnd = data.readShortLE();
            ts = data.readIntLE();
            sn = data.readIntLE();
            una = data.readIntLE();
            len = data.readIntLE();
            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:
                    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:
                    probe |= IKCP_ASK_TELL;
                    break;
                case IKCP_CMD_WINS:
                    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;
    }
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 ) { boolean 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 . readIntLE ( ) ; if ( this . conv != conv_ ) { return - 1 ; } cmd = data . readByte ( ) ; frg = data . readByte ( ) ; wnd = data . readShortLE ( ) ; ts = data . readIntLE ( ) ; sn = data . readIntLE ( ) ; una = data . readIntLE ( ) ; len = data . readIntLE ( ) ; 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 : 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 : probe |= IKCP_ASK_TELL ; break ; case IKCP_CMD_WINS : 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 ; }
when you received a low level packet (eg.
when you received a low level packet ( eg .
// ready to send back IKCP_CMD_WINS in Ikcp_flush // tell remote my window size // do nothing