Ejemplo n.º 1
0
        protected void ProcessUDPPackage(UDPPackageType pt, byte[] data)
        {
            //UDPPackageType pt = UDPMeta.GetPackageType(data);
            long sid = BitConverter.ToInt64(data, 8);

            //Console.WriteLine("ProcessUDPPackage:" + sid + ":" + pt);

            if (pt == UDPPackageType.SessionError)
            {
                Close();
            }
            else if (pt == UDPPackageType.SessionClose)
            {
                Close();
            }

            if (pt == UDPPackageType.DataPost)
            {
                if (_closed)
                {
                    SendToPeer(UDPMeta.CreateSessionError(SessionId, "closed"));
                    return;
                }

                long peerminreadindex = BitConverter.ToInt64(data, 16);
                lock (_postmap)
                {
                    OnGetPeerMinRead(peerminreadindex);
                }

                long dataindex = BitConverter.ToInt64(data, 24);

                //Console.WriteLine("DataPost:" + dataindex);

                if (dataindex == _readminindex + 1)
                {
                    OnPost(data, 32, data.Length - 32);
                    _readminindex = dataindex;
                    byte[] buff;
                    while (_buffmap.TryGetValue(_readminindex + 1, out buff))
                    {
                        _readminindex++;
                        _buffmap.Remove(_readminindex);
                        OnPost(buff);
                    }
                    SendToPeer(UDPMeta.CreateDataRead(SessionId, _readminindex, dataindex));
                }
                else
                {
                    if (dataindex > _readmaxindex)
                    {
                        _readmaxindex = dataindex;
                    }
                    byte[] buff = new byte[data.Length - 32];
                    Buffer.BlockCopy(data, 32, buff, 0, buff.Length);
                    _buffmap[dataindex] = buff;
                }
            }
            if (pt == UDPPackageType.DataRead)
            {
                long peerminreadindex = BitConverter.ToInt64(data, 16);
                long dataindex        = BitConverter.ToInt64(data, 24);
                lock (_postmap)
                {
                    PostMapRemove(dataindex);
                    OnGetPeerMinRead(peerminreadindex);
                }
            }
            if (pt == UDPPackageType.DataMiss)
            {
                long peerminreadindex = BitConverter.ToInt64(data, 16);
                lock (_postmap)
                {
                    OnGetPeerMinRead(peerminreadindex);
                }

                int             misscount = (data.Length - 24) / 8;
                List <DataItem> list      = null;
                for (int missid = 0; missid < misscount; missid++)
                {
                    long     dataindex = BitConverter.ToInt64(data, 24 + missid * 8);
                    DataItem item      = null;
                    lock (_postmap)
                    {
                        _postmap.TryGetValue(dataindex, out item);
                    }
                    if (item != null)
                    {
                        if (list == null)
                        {
                            list = new List <DataItem>();
                        }
                        list.Add(item);
                    }
                }
                if (list != null)
                {
                    list.Sort(delegate(DataItem d1, DataItem d2)
                    {
                        return(d1.SendTime.CompareTo(d2.SendTime));
                    });
                    int maxsendagain = 65536;

                    foreach (DataItem item in list)
                    {
                        if (DateTime.Now - item.SendTime < TimeSpan.FromMilliseconds(GetPackageLostMS()))
                        {
                            break;
                        }
                        if (maxsendagain < item.UDPData.Length)
                        {
                            break;
                        }
                        maxsendagain -= item.UDPData.Length;
                        UDPMeta.UpdateDataRead(item.UDPData, _readminindex);
                        item.SendTime = DateTime.Now;
                        item.RetryCount++;
                        SendToPeer(item.UDPData);
                    }
                }
            }
            if (pt == UDPPackageType.DataPing)
            {
                long peerminreadindex = BitConverter.ToInt64(data, 16);
                lock (_postmap)
                {
                    OnGetPeerMinRead(peerminreadindex);
                }

                long        maxdataindex = BitConverter.ToInt64(data, 24);
                List <long> misslist     = null;
                for (long index = _readminindex + 1; index <= maxdataindex; index++)
                {
                    if (_buffmap.ContainsKey(index))
                    {
                        continue;
                    }
                    if (misslist == null)
                    {
                        misslist = new List <long>();
                    }
                    misslist.Add(index);
                    if (misslist.Count * 8 + 40 > UDPMeta.BestUDPSize)
                    {
                        break;
                    }
                }
                if (misslist != null)
                {
                    SendToPeer(UDPMeta.CreateDataMiss(SessionId, _readminindex, misslist.ToArray()));
                }
                else
                {
                    SendToPeer(UDPMeta.CreateDataRead(SessionId, _readminindex, _readminindex));
                }
            }
        }