protected byte[] GetReliableMsg() { if (_recvBuffer == null) { return(null); } //Queue is empty if (_recvBuffer.Count <= 0) { return(null); } int MaxPiece = _recvBuffer.Peek().MaxPiece; //No enough pieces if (_recvBuffer.Count < MaxPiece) { //Debug.Log(string.Format("Not Enough Packet, Need: {0}, Queue: {1}, Assembling: {2}", package.MaxPiece, _assmblingPackages.Count, _recvQueue.Count)); return(null); } int dataLength = 0; List <byte[]> resultData = new List <byte[]>(); //Debug.Log("MaxPiece: " + MaxPiece.ToString()); for (int i = 0; i < MaxPiece; i++) { RecvingPackage apackage = _recvBuffer.Dequeue(); /*StringBuilder sb = new StringBuilder(); * sb.Append("getPackage: "); * for (int j = 0; j < apackage.Data.Length; j++) * { * sb.Append(apackage.Data[j] + ", "); * } * Debug.Log(sb.ToString());*/ resultData.Add(apackage.Data); dataLength += apackage.Data.Length; } byte[] ret = new byte[dataLength]; int currentPos = 0; for (int i = 0; i < resultData.Count; i++) { byte[] Data = resultData[i]; Data.CopyTo(ret, currentPos); currentPos += Data.Length; } return(ret); }
//DateTime lastTime; void ProcessRecvQueue(byte[] rawData, int len) { MemoryStream msgStream = new MemoryStream(rawData); BinaryReader reader = new BinaryReader(msgStream); //CRC byte[] checksumBytes = reader.ReadBytes(2); //SESSION byte[] sessionBytes = reader.ReadBytes(4); if (BitConverter.IsLittleEndian) { Array.Reverse(sessionBytes); } UInt32 sessionID = BitConverter.ToUInt32(sessionBytes, 0); //Discard mismatch session package if (sessionID != this.SessionID) { return; } //UNA byte[] unaBytes = reader.ReadBytes(4); if (BitConverter.IsLittleEndian) { Array.Reverse(unaBytes); } UInt32 coUna = BitConverter.ToUInt32(unaBytes, 0); len -= PublicFrameHeaderLength; uint maxAckSeq = 0; while (len > 0) { //len byte[] lenBytes = reader.ReadBytes(2); if (BitConverter.IsLittleEndian) { Array.Reverse(lenBytes); } ushort currentLen = BitConverter.ToUInt16(lenBytes, 0); len -= (currentLen + 2); //Get controll bits byte control = reader.ReadByte(); if (control == (byte)PACKAGE_CATE.DATA) { //this is a data frame byte[] seqDataBytes = reader.ReadBytes(4); if (BitConverter.IsLittleEndian) { Array.Reverse(seqDataBytes); } UInt32 seqData = BitConverter.ToUInt32(seqDataBytes, 0); byte[] maxPieceBytes = reader.ReadBytes(2); if (BitConverter.IsLittleEndian) { Array.Reverse(maxPieceBytes); } ushort maxPiece = BitConverter.ToUInt16(maxPieceBytes, 0); byte[] data = reader.ReadBytes(currentLen - DataFrameHeaderLength + 2); if (seqData > _una && seqData < _una + MaxRecvWindSize) { int recvQueuePos = (int)(seqData - _una - 1); if (_recvQueue[recvQueuePos] == null) { //replace dummy packages RecvingPackage recvPackage = new RecvingPackage(); recvPackage.Data = data; recvPackage.MaxPiece = maxPiece; recvPackage.RecvingSequenceNo = seqData; _recvQueue[recvQueuePos] = recvPackage; //Calculate una int i = 0; for (; i < _recvQueue.Count; i++, _una++) { if (_recvQueue[i] == null) { break; } else { _recvBuffer.Enqueue(_recvQueue[i]); _recvQueue.Add(null); } } _recvQueue.RemoveRange(0, i); } SendAck(seqData); } } else if (control == (byte)PACKAGE_CATE.ACK) //ACK, FIN+ACK { byte[] seqDataBytes = reader.ReadBytes(4); if (BitConverter.IsLittleEndian) { Array.Reverse(seqDataBytes); } UInt32 seqData = BitConverter.ToUInt32(seqDataBytes, 0); //Debug.Log("Recv Ack SeqNo: " + seqData.ToString()); SendingPackage sendPackage = _waitAckList.Find((SendingPackage input) => input.SendingSequenceNo == seqData); if (sendPackage != null) { int newPing = (int)(Clock - sendPackage.FirstSendTimestamp); MobaNetworkManager.Instance.AddPing(newPing); _waitAckList.Remove(sendPackage); if (maxAckSeq < seqData) { maxAckSeq = seqData; } } //Get an ack, set all rto to default RTO = DEFAULT_RTO; for (int i = 0; i < _waitAckList.Count; i++) { _waitAckList[i].RetransmissionInterval = RTO; } } else { Debug.LogError("Receive Illegal Package"); } } //fastack for (int i = 0; i < _waitAckList.Count; i++) { if (_waitAckList[i].SendingSequenceNo < maxAckSeq) { _waitAckList[i].fastack++; } } //process correspondance's una ProcessCoUna(coUna); }