src/main/java/org/beykery/jkcp/Kcp.java
public int receive(ByteBuf buffer) {
        if (rcv_queue.isEmpty()) {
            return -1;
        }
        int peekSize = peekSize();
        if (peekSize < 0) {
            return -2;
        }
        boolean recover = rcv_queue.size() >= rcv_wnd;
        // merge fragment.
        int c = 0;
        int len = 0;
        for (Segment seg : rcv_queue) {
            len += seg.data.readableBytes();
            buffer.writeBytes(seg.data);
            c++;
            if (seg.frg == 0) {
                break;
            }
        }
        if (c > 0) {
            for (int i = 0; i < c; i++) {
                rcv_queue.removeFirst().data.release();
            }
        }
        if (len != peekSize) {
            throw new RuntimeException("数据异常.");
        }
        // move available data from rcv_buf -> rcv_queue
        c = 0;
        for (Segment seg : rcv_buf) {
            if (seg.sn == rcv_nxt && rcv_queue.size() < rcv_wnd) {
                rcv_queue.add(seg);
                rcv_nxt++;
                c++;
            } else {
                break;
            }
        }
        if (c > 0) {
            for (int i = 0; i < c; i++) {
                rcv_buf.remove(0);
            }
        }
        // fast recover
        if (rcv_queue.size() < rcv_wnd && recover) {
            // ready to send back IKCP_CMD_WINS in ikcp_flush
            // tell remote my window size
            probe |= IKCP_ASK_TELL;
        }
        return len;
    }
/**
     * user/upper level recv: returns size, returns below zero for EAGAIN
     *
     * @param buffer
     * @return
     */
user/upper level recv: returns size, returns below zero for EAGAIN
@param buffer
@return
user / upper level recv : returns size returns below zero for EAGAIN @param buffer @return
public int receive(ByteBuf buffer) {
        if (rcv_queue.isEmpty()) {
            return -1;
        }
        int peekSize = peekSize();
        if (peekSize < 0) {
            return -2;
        }
        boolean recover = rcv_queue.size() >= rcv_wnd;
        int c = 0;
        int len = 0;
        for (Segment seg : rcv_queue) {
            len += seg.data.readableBytes();
            buffer.writeBytes(seg.data);
            c++;
            if (seg.frg == 0) {
                break;
            }
        }
        if (c > 0) {
            for (int i = 0; i < c; i++) {
                rcv_queue.removeFirst().data.release();
            }
        }
        if (len != peekSize) {
            throw new RuntimeException("数据异常.");
        }
        c = 0;
        for (Segment seg : rcv_buf) {
            if (seg.sn == rcv_nxt && rcv_queue.size() < rcv_wnd) {
                rcv_queue.add(seg);
                rcv_nxt++;
                c++;
            } else {
                break;
            }
        }
        if (c > 0) {
            for (int i = 0; i < c; i++) {
                rcv_buf.remove(0);
            }
        }
        if (rcv_queue.size() < rcv_wnd && recover) {
            probe |= IKCP_ASK_TELL;
        }
        return len;
    }
public int receive ( ByteBuf buffer ) { if ( rcv_queue . isEmpty ( ) ) { return - 1 ; } int peekSize = peekSize ( ) ; if ( peekSize < 0 ) { return - 2 ; } boolean recover = rcv_queue . size ( ) >= rcv_wnd ; int c = 0 ; int len = 0 ; for ( Segment seg : rcv_queue ) { len += seg . data . readableBytes ( ) ; buffer . writeBytes ( seg . data ) ; c ++ ; if ( seg . frg == 0 ) { break ; } } if ( c > 0 ) { for ( int i = 0 ; i < c ; i ++ ) { rcv_queue . removeFirst ( ) . data . release ( ) ; } } if ( len != peekSize ) { throw new RuntimeException ( "数据异常."); } c = 0 ; for ( Segment seg : rcv_buf ) { if ( seg . sn == rcv_nxt && rcv_queue . size ( ) < rcv_wnd ) { rcv_queue . add ( seg ) ; rcv_nxt ++ ; c ++ ; } else { break ; } } if ( c > 0 ) { for ( int i = 0 ; i < c ; i ++ ) { rcv_buf . remove ( 0 ) ; } } if ( rcv_queue . size ( ) < rcv_wnd && recover ) { probe |= IKCP_ASK_TELL ; } return len ; }
user/upper level recv: returns size, returns below zero for EAGAIN
 @param buffer
 @return
user / upper level recv : returns size returns below zero for EAGAIN @param buffer @return
// merge fragment. // move available data from rcv_buf -> rcv_queue // fast recover // ready to send back IKCP_CMD_WINS in ikcp_flush // tell remote my window size