Ejemplo n.º 1
0
        void OnTimer(object argstate)
        {
            if (_closed)
            {
                _timer.Dispose();
                return;
            }

            if (_postmap.Count == 0)
            {
                return;
            }

            if (DateTime.Now - _timerlastitem.SendTime < TimeSpan.FromMilliseconds(GetPackageLostMS()))
            {
                return;
            }


            if (_timerlastitem.PingCount > 10)
            {
                return;
            }

            _timerlastitem.PingCount++;

            SendToPeer(UDPMeta.CreateDataPing(SessionId, _readminindex, _timerlastitem.DataIndex));
        }
Ejemplo n.º 2
0
        async Task ReadLoopAsync()
        {
            await Task.Yield();

            while (true)
            {
                //TODO: if not cached , and all stream closed , shutdown directly
                var data = await ReceiveAsync();

                if (data == null)
                {
                    Console.WriteLine("_udp.ReceiveAsync() return null ,Close()");
                    Close();
                    return;
                }
                long sid = BitConverter.ToInt64(data, 8);
                if (sid == -1)
                {
                    Console.WriteLine("_udp.ReceiveAsync() return " + sid + ", " + UDPMeta.GetPackageType(data));
                }

                UDPBufferReader reader = GetBufferReader(sid);
                reader.OnPost(data);
            }
        }
Ejemplo n.º 3
0
 public override void Close()
 {
     _closed = true;
     if (_timer != null)
     {
         _timer.Dispose();
     }
     base.Close();
     if (!_closesend)
     {
         _closesend = true;
         SendToPeer(UDPMeta.CreateSessionError(SessionId, "Close"));
     }
 }
Ejemplo n.º 4
0
            public void Process(UDPPackageType pt, byte[] data)
            {
                if (_waitfor == pt)
                {
                    TcpMapService.LogMessage("UDPServer:" + pt);

                    if (pt == UDPPackageType.SessionConnect)
                    {
                        UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(data, 16, data.Length - 16));
                        if (udpc.token != this.ConnectToken)
                        {
                            _sl.RejectConnect(this);
                            return;
                        }
                        byte[] buffprepair = UDPMeta.CreateSessionPrepair(SessionId, ConnectToken);
                        SendToPeer(buffprepair); SendToPeer(buffprepair);
                        _waitfor = UDPPackageType.SessionConfirm;
                        return;
                    }
                    if (pt == UDPPackageType.SessionConfirm)
                    {
                        UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(data, 16, data.Length - 16));
                        if (udpc.token != this.ConnectToken)
                        {
                            _sl.RejectConnect(this);
                            return;
                        }
                        byte[] buffready = UDPMeta.CreateSessionReady(SessionId, ConnectToken);
                        SendToPeer(buffready); SendToPeer(buffready);
                        _waitfor = UDPPackageType.SessionIdle;
                        _reader  = new BufferedReader(cts.Token);
                        ThreadPool.QueueUserWorkItem(delegate
                        {
                            _sl._onstream(this, RemoteEndPoint);
                        });
                        return;
                    }
                    if (pt == UDPPackageType.SessionIdle)
                    {
                        SendToPeer(UDPMeta.CreateSessionIdle(SessionId));
                        return;
                    }
                }
                else
                {
                    ProcessUDPPackage(pt, data);
                }
            }
Ejemplo n.º 5
0
        private void RejectConnect(ServerStream stream)
        {
            long sid     = stream.SessionId;
            bool removed = false;

            lock (this.strmap)
            {
                if (this.strmap.TryGetValue(sid, out ServerStream ss))
                {
                    if (ss == stream)
                    {
                        this.strmap.Remove(sid);
                        removed = true;
                    }
                }
            }
            if (removed)
            {
                this.udp.SendToClient(stream.RemoteEndPoint, UDPMeta.CreateSessionError(sid, "Reject"));
            }
        }
Ejemplo n.º 6
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)
            {
                this.Close();
            }
            else if (pt == UDPPackageType.SessionClose)
            {
                this.Close();
            }

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

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

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

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

                if (dataindex == this.readminindex + 1)
                {
                    this.OnPost(data, 32, data.Length - 32);
                    this.readminindex = dataindex;
                    while (this.buffmap.TryGetValue(this.readminindex + 1, out byte[] buff))
Ejemplo n.º 7
0
        void ClientWorkThread()
        {
            try
            {
                while (true)
                {
                    //TODO:when timeout , try to send idle message
                    byte[] data = _udp.Receive(SessionId, TimeSpan.FromSeconds(40));
                    if (data == null)
                    {
                        if (!_reader._removed)
                        {
                            Console.WriteLine("UDPClientStream.ClientWorkThread.Timeout-40");
                        }

                        _reader.OnRemoved();

                        base.OnWorkerThreadExit();

                        return;
                    }

                    try
                    {
                        UDPPackageType pt = UDPMeta.GetPackageType(data);
                        ProcessUDPPackage(pt, data);
                    }
                    catch (Exception x)
                    {
                        TcpMapService.OnError(x);
                    }
                }
            }
            catch (Exception x)
            {
                TcpMapService.OnError(x);
            }
        }
Ejemplo n.º 8
0
        //public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
        //{
        //	return base.WriteAsync(buffer, cancellationToken);
        //}

        public override void Write(byte[] buffer, int offset, int count)
        {
            if (_closed)
            {
                throw (new Exception("stream closed"));
            }

            //Console.WriteLine("UDPBaseStream write " + count);

            while (count > UDPMeta.BestUDPSize)
            {
                Write(buffer, offset, UDPMeta.BestUDPSize);
                offset += UDPMeta.BestUDPSize;
                count  -= UDPMeta.BestUDPSize;
            }


            DataItem item = new DataItem();

            item.DataIndex = ++nextdataindex;

            item.UDPData = UDPMeta.CreateDataPost(SessionId, _readminindex, item.DataIndex, buffer, offset, count);

            lock (_postmap)
            {
                _postmap[item.DataIndex] = item;
            }

            item.SendTime = DateTime.Now;
            SendToPeer(item.UDPData);

            _timerlastitem = item;
            if (_timer == null)
            {
                _timer = new Timer(OnTimer, null, 100, 100);
            }
        }
Ejemplo n.º 9
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));
                }
            }
        }
Ejemplo n.º 10
0
        void ListenerWorkThread()
        {
            while (this._workthread != null)
            {
                try
                {
                    //TODO: if not cached , and all stream closed , shutdown directly

                    IPEndPoint ep;
                    byte[]     data = _udp.Receive(TimeSpan.FromSeconds(90), out ep);
                    if (data == null)
                    {
                        Console.WriteLine("_udp.Receive return null for a long time...; Shutdown..." + this._udp.LocalEndPoint);
                        this.Close();
                        return;
                    }

                    UDPPackageType pt = UDPMeta.GetPackageType(data);
                    if (pt == UDPPackageType.Unknown)
                    {
                        //Console.WriteLine("_udp.Receive return Unknown;");
                        return;
                    }

                    long         sid = BitConverter.ToInt64(data, 8);
                    ServerStream ss;

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

                    if (pt == UDPPackageType.SessionConnect)
                    {
                        UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(data, 16, data.Length - 16));
                        lock (strmap)
                        {
                            if (!strmap.TryGetValue(sid, out ss))
                            {
                                ss          = new ServerStream(this, sid, ep, udpc);
                                strmap[sid] = ss;
                            }
                        }
                        if (ss.ConnectToken != udpc.token)
                        {
                            ss.ForceClose();
                            lock (strmap)
                            {
                                ss          = new ServerStream(this, sid, ep, udpc);
                                strmap[sid] = ss;
                            }
                        }
                        else
                        {
                            ss.Process(pt, data);
                        }
                    }
                    else
                    {
                        lock (strmap)
                        {
                            strmap.TryGetValue(sid, out ss);
                        }
                        if (ss != null)
                        {
                            ss.Process(pt, data);
                        }
                        else
                        {
                            _udp.SendToClient(ep, UDPMeta.CreateSessionError(sid, "NotFound"));
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    break;
                }
                catch (Exception x)
                {
                    TcpMapService.OnError(x);
                }
            }
        }
Ejemplo n.º 11
0
        void _Connect(UDPClientListener udp, string ip, int port, TimeSpan timeout)
        {
            _udp = udp;

StartConnect:

            SessionId = Interlocked.Increment(ref _nextsessionid);

            string guid = Guid.NewGuid().ToString();

            byte[] buffconnect = UDPMeta.CreateSessionConnect(SessionId, guid);
            SendToPeer(buffconnect); SendToPeer(buffconnect);
            while (true)
            {
                byte[] buffprepair = _udp.Receive(SessionId, TimeSpan.FromMilliseconds(500));
                if (buffprepair == null)
                {
                    CheckTimeout(timeout);
                    Console.WriteLine("Client StartConnect Again");
                    //SendToPeer(buffconnect); SendToPeer(buffconnect);
                    //continue;
                    goto StartConnect;
                }
                UDPPackageType ptprepair = UDPMeta.GetPackageType(buffprepair);
                if (ptprepair != UDPPackageType.SessionPrepair)
                {
                    if (ptprepair > UDPPackageType.SessionPrepair)
                    {
                        goto StartConnect;
                    }
                    continue;
                }
                long sidprepair = BitConverter.ToInt64(buffprepair, 8);
                if (sidprepair != SessionId)
                {
                    goto StartConnect;
                }
                UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(buffprepair, 16, buffprepair.Length - 16));
                if (udpc.token != guid)
                {
                    goto StartConnect;
                }
                break;
            }
            byte[] buffconfirm = UDPMeta.CreateSessionConfirm(SessionId, guid);
            SendToPeer(buffconfirm); SendToPeer(buffconfirm);
            while (true)
            {
                byte[] buffready = _udp.Receive(SessionId, TimeSpan.FromMilliseconds(500));
                if (buffready == null)
                {
                    CheckTimeout(timeout);
                    SendToPeer(buffconfirm); SendToPeer(buffconfirm);
                    continue;
                }
                UDPPackageType ptprepair = UDPMeta.GetPackageType(buffready);
                if (ptprepair != UDPPackageType.SessionReady)
                {
                    if (ptprepair > UDPPackageType.SessionReady)
                    {
                        goto StartConnect;
                    }
                    continue;
                }
                long sidprepair = BitConverter.ToInt64(buffready, 8);
                if (sidprepair != SessionId)
                {
                    goto StartConnect;
                }
                UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(buffready, 16, buffready.Length - 16));
                if (udpc.token != guid)
                {
                    goto StartConnect;
                }
                break;
            }

            _reader = new ClientBufferReader();
            Thread t = new Thread(ClientWorkThread);            //TODO:Convert to async

            t.IsBackground = true;
            t.Start();
        }