/** * 分帧逻辑 * **/ public ByteBuf TranslateFrame(ByteBuf src) { while (src.ReadableBytes() > 0) { switch (status) { case 0: h = src.ReadByte(); status = 1; break; case 1: l = src.ReadByte(); len = (short)(((h << 8)&0x0000ff00) | (l)); frame = new ByteBuf(len + 2); frame.WriteShort(len); status = 2; break; case 2: int min=frame.WritableBytes(); min=src.ReadableBytes()<min?src.ReadableBytes():min; if(min>0) { frame.WriteBytes(src,min); } if (frame.WritableBytes() <= 0) { status = 0; return frame; } break; } } return null; }
/** * 分帧逻辑 * **/ public ByteBuf TranslateFrame(ByteBuf src) { while (src.ReadableBytes() > 0) { switch (status) { case 0: h = src.ReadByte(); status = 1; break; case 1: l = src.ReadByte(); len = (short)(((h << 8) & 0x0000ff00) | (l)); frame = new ByteBuf(len + 2); frame.WriteShort(len); status = 2; break; case 2: frame.WriteBytes(src); if (frame.WritableBytes() <= 0) { status = 0; return(frame); } break; } } return(null); }
/** * 分帧逻辑 * **/ public ByteBuf TranslateFrame(ByteBuf src) { while (src.ReadableBytes() > 0) { switch (status) { case 0: h = src.ReadByte(); status = 1; break; case 1: hl = src.ReadByte(); status = 2; break; case 2: lh = src.ReadByte(); status = 3; break; case 3: l = src.ReadByte(); len = h << 24 | hl << 16 | lh << 8 | l; frame = new ByteBuf(len + 4); frame.WriteInt(len); status = 4; break; case 4: int min = frame.WritableBytes(); min = src.ReadableBytes() < min?src.ReadableBytes() : min; if (min > 0) { frame.WriteBytes(src, min); } if (frame.WritableBytes() <= 0) { status = 0; return(frame); } break; } } return(null); }
/** * 分帧逻辑 * **/ public ByteBuf TranslateFrame(ByteBuf src) { while (src.ReadableBytes() > 0) { switch (status) { case STATUS_HEADER: for (; index < header.Length; index++) { if (!(src.ReadableBytes() > 0)) { break; } header[index] = (sbyte)src.ReadByte(); if (header[index] >= 0) { int length = 0; length = CodedInputStream.newInstance(header, 0, index + 1).readRawVarint32(); if (length < 0) { return(null); } len = length; headerLen = CodedOutputStream.computeRawVarint32Size(len); Console.WriteLine(":" + len + ":" + headerLen); incompleteframe = new ByteBuf(len + headerLen); CodedOutputStream headerOut = CodedOutputStream.newInstance(incompleteframe, headerLen); headerOut.writeRawVarint32(len); headerOut.flush(); status = STATUS_CONTENT; break; } } break; case STATUS_CONTENT: int l = Math.Min(src.ReadableBytes(), incompleteframe.WritableBytes()); if (l > 0) { incompleteframe.WriteBytes(src, l); } if (incompleteframe.WritableBytes() <= 0) { status = STATUS_HEADER; index = 0; return(incompleteframe); } break; } } return(null); }
/** * 分帧逻辑 * **/ public ByteBuf TranslateFrame(ByteBuf src) { while (src.ReadableBytes() > 0) { switch (status) { case STATUS_HEADER: for (; index < header.Length; index++) { if (!(src.ReadableBytes() > 0)) { break; } header[index] = (sbyte)src.ReadByte(); if (header[index] >= 0) { int length = 0; length = CodedInputStream.newInstance(header, 0, index + 1).readRawVarint32(); if (length < 0) { return null; } len = length; headerLen = CodedOutputStream.computeRawVarint32Size(len); Console.WriteLine (":"+len+":"+headerLen); incompleteframe = new ByteBuf(len + headerLen); CodedOutputStream headerOut = CodedOutputStream.newInstance(incompleteframe, headerLen); headerOut.writeRawVarint32(len); headerOut.flush(); status = STATUS_CONTENT; break; } } break; case STATUS_CONTENT: int l = Math.Min(src.ReadableBytes(), incompleteframe.WritableBytes()); if (l > 0) { incompleteframe.WriteBytes(src, l); } if (incompleteframe.WritableBytes() <= 0) { status = STATUS_HEADER; index = 0; return incompleteframe; } break; } } return null; }
/** * 分帧逻辑 * **/ public ByteBuf TranslateFrame(ByteBuf src) { while (src.ReadableBytes() > 0) { switch (status) { case 0: //获取长度高位 h = src.ReadByte(); status = 1; break; case 1: //获取长度低位 l = src.ReadByte(); len = (short)(((h << 8) & 0x0000ff00) | (l)); frame = new ByteBuf(len + 2); frame.WriteShort(len); //写入长度先 status = 2; break; case 2: int min = frame.WritableBytes(); //当前帧可写入的 min = src.ReadableBytes() < min?src.ReadableBytes() : min; if (min > 0) { frame.WriteBytes(src, min); } if (frame.WritableBytes() <= 0) { status = 0; //帧写满了 return(frame); } break; } } return(null); }
/** * * 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.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 */ 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); }