Example #1
0
        private List <SendingPackage> Capsule(byte[] data)
        {
            List <SendingPackage> ret = new List <SendingPackage>();
            int    frameNum           = (data.Length + (MTU - DataFrameHeaderLength - PublicFrameHeaderLength) - 1) / (MTU - DataFrameHeaderLength - PublicFrameHeaderLength);
            ushort currentPosition    = 0;

            for (int i = 0; i < frameNum; i++)
            {
                ushort       dataLength = (ushort)Math.Min(MTU - DataFrameHeaderLength - PublicFrameHeaderLength, data.Length - currentPosition);
                byte[]       frame      = new byte[dataLength + DataFrameHeaderLength];
                MemoryStream ms         = new MemoryStream(frame);
                BinaryWriter bw         = new BinaryWriter(ms);
                byte[]       lenBytes   = BitConverter.GetBytes((ushort)(dataLength + 7));
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(lenBytes);
                }
                bw.Write(lenBytes); //0 len
                bw.Write((byte)4);  //2 control
                byte[] currentSendSeqBytes = BitConverter.GetBytes(_currentSnedSeq);
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(currentSendSeqBytes);
                }
                bw.Write(currentSendSeqBytes);//3 seqNo
                byte[] maxPieceBytes = BitConverter.GetBytes((ushort)frameNum);
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(maxPieceBytes);
                }
                bw.Write(maxPieceBytes);                     //7 max piece
                bw.Write(data, currentPosition, dataLength); //9 data
                bw.Close();
                SendingPackage package = new SendingPackage();

                package.Content                = frame;
                package.SendingSequenceNo      = _currentSnedSeq;
                package.fastack                = 0;
                package.RetransmissionInterval = RTO;
                _currentSnedSeq++;
                currentPosition += dataLength;
                ret.Add(package);
            }
            return(ret);
        }
Example #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);
        }
Example #3
0
        byte[] SendStreamBuffer = new byte[MTU]; // for final frame construction
        void ProcessSendQueue(float deltaTime)
        {
            //Put available packages to waiting dict
            int readyToSendNum = 0;

            readyToSendNum = Math.Min(MaxWaitingSendLength - _waitAckList.Count, _sendQueue.Count);
            for (int i = 0; i < readyToSendNum; i++)
            {
                SendingPackage package = _sendQueue.Dequeue();
                _sendBuffer.Enqueue(package.Content);
                package.LastSendTimestamp  = Clock;
                package.FirstSendTimestamp = Clock;
                _waitAckList.Add(package);
            }

            //Re-send un-acked packages
            //string pendingList = "";
            for (int i = 0; i < _waitAckList.Count; i++)
            {
                SendingPackage package        = _waitAckList[i];
                float          elapsedTime    = Clock - package.LastSendTimestamp;
                bool           needRetransmit = elapsedTime > package.RetransmissionInterval;
                bool           fastack        = package.fastack >= 2;
                if (needRetransmit || fastack)
                {
                    _sendBuffer.Enqueue(package.Content);
                    package.LastSendTimestamp = Clock;
                    if (fastack)
                    {
                        package.fastack = 0;
                    }
                    else if (needRetransmit)
                    {
                        RTO = (uint)(RTO * 1.5 > MAX_RTO ? MAX_RTO : RTO * 1.5);
                        package.RetransmissionInterval = RTO;
                    }
                }
            }

            int currentPos = PublicFrameHeaderLength;
            //actually send
            int iWaitAck = 0;

            while (_sendBuffer.Count > 0)
            {
                byte[] nextSendContent = _sendBuffer.Dequeue();
                if (currentPos + nextSendContent.Length > MTU)
                {
                    for (; iWaitAck < _waitAckList.Count; iWaitAck++)
                    {
                        if (Clock - _waitAckList[iWaitAck].LastSendTimestamp < 0.001f)
                        {
                            continue;
                        }
                        nextSendContent = _waitAckList[iWaitAck].Content;
                        if (currentPos + nextSendContent.Length > MTU)
                        {
                            break;
                        }
                        Array.Copy(nextSendContent, 0, SendStreamBuffer, currentPos, nextSendContent.Length);
                        currentPos += nextSendContent.Length;
                    }

                    Send(SendStreamBuffer, currentPos);
                    currentPos = PublicFrameHeaderLength;
                }
                Array.Copy(nextSendContent, 0, SendStreamBuffer, currentPos, nextSendContent.Length);
                currentPos += nextSendContent.Length;
            }
            if (currentPos > PublicFrameHeaderLength)
            {
                for (; iWaitAck < _waitAckList.Count; iWaitAck++)
                {
                    if (Clock - _waitAckList[iWaitAck].LastSendTimestamp < 0.001f)
                    {
                        continue;
                    }
                    byte[] nextSendContent = _waitAckList[iWaitAck].Content;
                    if (currentPos + nextSendContent.Length > MTU)
                    {
                        break;
                    }
                    Array.Copy(nextSendContent, 0, SendStreamBuffer, currentPos, nextSendContent.Length);
                    currentPos += nextSendContent.Length;
                }

                Send(SendStreamBuffer, currentPos);
            }
        }