private void Check(byte[] data) { int index = 0; var conv = ConverHelper.GetU32(data, index); Tuple <Queue <KCPPackage>, KCP> item = null; lock (SessionDic) { if (!SessionDic.TryGetValue(conv, out item)) { item = new Tuple <Queue <KCPPackage>, KCP>(new Queue <KCPPackage>(), new KCP(conv)); //如果会话中不存在conv则认为这是新连接,创建KCP状态机 SessionDic.Add(conv, item); new Thread(Update) { IsBackground = true }.Start(item); } } while (index < data.Length) { var tempItem = KCPPackage.Parse(data, index); if (tempItem.Item2 == 0) { break; } index += tempItem.Item2; item.Item1.Enqueue(tempItem.Item1); } }
private KCPPackage CreateSendPack(int size, byte frg) { var result = new KCPPackage(); result.Data = new byte[size]; result.Length = (uint)size; result.Frg = frg; return(result); }
public int SendMsg(byte[] data) { if (data == null || data.Length == 0) { return(-1); } int count = 1; if (data.Length > mss) { count = (data.Length + mss - 1) / mss; } if (count > 255) { return(-2); } if (send_queue.Length > Max) { return(-3); } int offset = 0; for (int i = 0; i < count; i++) { KCPPackage pack = null; if (count - 1 == i) { pack = CreateSendPack(data.Length - offset, 0); Array.Copy(data, offset, pack.Data, 0, pack.Data.Length); send_queue = append <KCPPackage>(send_queue, pack); break; } pack = CreateSendPack(mss, (byte)(count - i - 1)); Array.Copy(data, offset, pack.Data, 0, pack.Data.Length); send_queue = append <KCPPackage>(send_queue, pack); offset += mss; } return(0); }
public static Tuple <KCPPackage, int> Parse(byte[] data, int index) { if (data.Length - index < 24) { return(defaultval); } var pack = new KCPPackage(); pack.Conv = ConverHelper.GetU32(data, index); pack.Cmd = ConverHelper.GetU8(data, index + 4); pack.Frg = ConverHelper.GetU8(data, index + 5); pack.Wnd = ConverHelper.GetU16(data, index + 6); pack.Ts = ConverHelper.GetU16(data, index + 8); pack.Sn = ConverHelper.GetU16(data, index + 12); pack.Una = ConverHelper.GetU16(data, index + 16); pack.Length = ConverHelper.GetU16(data, index + 20); if ((data.Length - index - headlength) < pack.Length) { return(defaultval); } pack.Data = data.Skip(index + headlength).Take((int)pack.Length).ToArray(); return(new Tuple <KCPPackage, int>(pack, (int)pack.Length + headlength)); }
public int input(KCPPackage data) { if (data.Conv != this._conv) { return(-1); } if (data.Cmd < 81 || data.Cmd > 84) { return(-2); } remoteRecvWnd = data.Wnd; int needAckedCount = 0; for (int i = 0; i < this.send_buf.Length; i++) { if (data.Una > send_buf[i].Sn) { needAckedCount++; } else { break; } } if (needAckedCount > 0) { this.send_buf = slice <KCPPackage>(this.send_buf, needAckedCount, this.send_buf.Length); } if (data.Cmd == 82)//ack { if (this.send_buf.Length > 0) { if (this.send_buf[0].Sn <= data.Sn) { int index = 0; foreach (var pack in this.send_buf) { if (pack.Sn == data.Sn) { this.send_buf = append <KCPPackage>(slice <KCPPackage>(this.send_buf, 0, index), slice <KCPPackage>(this.send_buf, index + 1, send_buf.Length)); break; } else { pack.fastack++; } index++; } } } } if (data.Cmd == 81)//push { if (this.rcv_next + this.rcv_wnd > data.Sn) { //添加到待回执列表 append <Tuple <UInt32, UInt32> >(this.acklist, new Tuple <UInt32, UInt32>(data.Sn, )) bool exist = false; int topper = -1; if (this.rcv_next <= data.Sn) { for (int i = 0; i < this.recv_buff.Length; i++) { var pack = this.recv_buff[i]; if (pack.Sn == data.Sn) { exist = true; break; } if (data.Sn > pack.Sn) { topper = i; break; } } } if (!exist) { if (topper == -1) { recv_buff = append <KCPPackage>(recv_buff, data); } else { recv_buff = append <KCPPackage>(slice <KCPPackage>(recv_buff, 0, topper), append <KCPPackage>(new KCPPackage[] { data }, slice <KCPPackage>(recv_buff, topper + 1, recv_buff.Length))); } } int removecount = 0; foreach (var pack in this.recv_buff) { if (this.rcv_next == pack.Sn) { this.recv_queue = append <KCPPackage>(this.recv_queue, pack); this.rcv_next++; removecount++; } } if (removecount > 0) { this.recv_buff = slice <KCPPackage>(this.recv_buff, removecount, this.recv_buff.Length); } } } if (data.Cmd == 83) { //todo wnd ask } if (data.Cmd == 84) { } return(0); }