Пример #1
0
        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);
        }
Пример #2
0
        //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);
        }