コード例 #1
0
        protected virtual void TimeoutCheck(object state)
        {
            if (!IsConnected)
            {
                return;
            }

            if ((DateTime.Now - LastReceivedTime).TotalMilliseconds >= Timeout.TotalMilliseconds)
            {
                Logger.Trace("Ping无应答,连接丢失");
                Close();
                return;
            }


            if ((DateTime.Now - LastReceivedTime).TotalMilliseconds >= checkTimeInterval)
            {
                UdpFrame ping = new UdpFrame(0, 0, 0, UdpCommand.Ping, null, 0);
                SendFrame(ping, Target);
            }
            lock (timerLocker)
            {
                if (checkTimer != null)
                {
                    checkTimer.Change(checkTimeInterval, System.Threading.Timeout.Infinite);
                }
            }
        }
コード例 #2
0
        public override void Close()
        {
            if (IsConnected)
            {
                Logger.Trace("关闭会话:{0}", Target);
                Logger.Trace(Environment.StackTrace);
                UdpFrame frame = new UdpFrame(0, 0, 0, UdpCommand.Close, null, Session.ProxyID);
                try
                {
                    InnerSendFrame(frame, Target);
                }
                catch (Exception e)
                {
                }
            }
            //Client.Close();
            bool oldConnected = IsConnected;

            IsConnected = false;
            if (oldConnected)
            {
                OnClosed();
            }
            IsConnected = false;
        }
コード例 #3
0
        //public List<UdpFrame> GetDataSendFrames()
        //{
        //    return sendedList.ToList();
        //}

        // private List<UdpFrame> sendedList = new List<UdpFrame>();
        internal void InnerSendFrame(UdpFrame frame, EndPoint target)
        {
            if (frame.Command == UdpCommand.Connect)
            {
                Logger.Trace("发送连接帧命令:{0}", target);
            }
            else if (frame.Command == UdpCommand.Data)
            {
                //lock (sendedList)
                //{
                //    sendedList.Add(frame);
                //}

                //Logger.Trace("发送数据包帧:{0} {1}", frame.PackageSeq, frame.Seq);
            }
            byte[] data = frame.UDPData;
            if (frameWrapper != null)
            {
                for (int i = 0; i < frameWrapper.Count; i++)
                {
                    data = frameWrapper[i].Wrapper(frame.UDPData, frame.Command);
                }
            }
            //if (frame.Command == UdpCommand.Data && frame.Length == (frame.Seq + 1))
            //{
            //    Logger.Trace("最后一帧:{0} {1} {2} {3}", frame.PackageSeq, frame.Seq, frame.Data.Length, data.Length);
            //    Logger.Trace("数据 :\r\n{0}", BitConverter.ToString(frame.Data));
            //}

            SendData(data, target, frame.ProxyID);
        }
コード例 #4
0
        protected override void OnReceivedData(byte[] data, System.Net.IPEndPoint ep, UInt16 proxyId, bool isText)
        {
            UdpServerSession session = getSession(ep.Address.ToString(), ep.Port, proxyId);

            if (session != null)
            {
                lock (session)
                {
                    session.ReceivedBytes  += (data == null ? 0 : data.Length);
                    session.ActiveTime      = DateTime.Now;
                    session.LastReceiveTime = DateTime.Now;
                }
                OnReceivedData(new ReceivedDataEventArgs(data, session, isText));
                session.RaiseReceivedData(data, isText);
            }
            else
            {
                UdpFrame frame = new UdpFrame(0, 0, 0, UdpCommand.UnConnected, null, proxyId);
                SendFrame(frame, ep);
            }
            //修改主连接会话最后接收时间
            session = getSession(ep.Address.ToString(), ep.Port, 0);
            if (session != null)
            {
                lock (session)
                {
                    session.ActiveTime = DateTime.Now;
                }
            }
        }
コード例 #5
0
        public void ReceivedFeedback(UdpFrame frame)
        {
            DateTime now       = DateTime.Now;
            UdpFrame dataFrame = null;

            lock (packageCache)
            {
                dataFrame = packageCache.ChangeFrameStatus(frame.PackageSeq, frame.Seq);
            }
            //EndPoint ep = null;
            //从正在发送的列表中移除
            //lock (sendingList)
            //{
            //    var si = sendingList.FirstOrDefault(x => x.Frame.PackageSeq == frame.PackageSeq && x.Frame.Seq == frame.Seq);
            //    if (si != null)
            //    {
            //        sendingList.Remove(si);
            //        ep = si.Target;
            //    }
            //}

            lock (packageCache)
            {
                UdpPackage up = packageCache.PackageList.FirstOrDefault(x => x.PackageID == frame.PackageSeq);

                if (up != null)
                {
                    long   cost = (long)(now - dataFrame.LastSendTime).TotalMilliseconds;
                    string key  = up.Target.ToString();
                    lock (avgSendCost)
                    {
                        if (avgSendCost.ContainsKey(key))
                        {
                            avgSendCost[key] = (avgSendCost[key] + cost) / 2;
                        }
                        else
                        {
                            avgSendCost.Add(key, cost);
                        }
                    }
                }

                if (up != null && up.Count(x => !x.IsSended) == 0)
                {
                    //    Logger.Trace("发送数据包成功:{0} {1}", up.PackageID, up.Data.Length);
                    //包发送完成
                    //packageCache.PackageList.Remove(up);
                    RemovePackage(up.PackageID, false);
                    OnSendPackageSuccess(up, up.Target, up[0].ProxyID);
                    if (up.Callback != null)
                    {
                        up.Callback(up, true);
                    }
                }
            }
        }
コード例 #6
0
        protected override UdpFrame OnReceivedFrameData(byte[] data, IPEndPoint ep)
        {
            if (data == null || data.Length < UdpFrame.HeadLength)
            {
                return(null);
            }


            UdpFrame frame = new UdpFrame(data);

            if (frame.Command == UdpCommand.ConnectConfirm)
            {
                Logger.Trace("收到连接确认应答帧:{0} {1}", ep, frame.ProxyID);
                if (frame.ProxyID == 0)
                {
                    RemoveCachePackage(ep);
                    //RealTarget = ep;
                    IsConnected = true;
                }
                ManualResetEvent wait = null;
                lock (connWaitList)
                {
                    if (connWaitList.ContainsKey(frame.ProxyID))
                    {
                        wait = connWaitList[frame.ProxyID];
                    }
                }
                if (wait != null)
                {
                    wait.Set();
                }

                return(null);
            }
            else if (frame.Command == UdpCommand.Close)
            {
                Logger.Trace("服务端关闭会话:{0}", ep);
                Close(false, frame.ProxyID);
            }
            else if (frame.Command == UdpCommand.UnConnected)
            {
                Logger.Trace("服务端返回未连接:{0}", ep);
                Close(false, frame.ProxyID);
            }
            else if (frame.Command == UdpCommand.Ping)
            {
                if (IsConnected)
                {
                    UdpFrame pong = new UdpFrame(0, 0, 0, UdpCommand.Pong, null, frame.ProxyID);
                    SendFrame(pong, ep);
                }
            }

            return(frame);
        }
コード例 #7
0
        protected virtual UdpFrame OnReceivedFrameData(byte[] data, IPEndPoint ep)
        {
            if (data == null || data.Length < UdpFrame.HeadLength)
            {
                return(null);
            }

            UdpFrame frame = new UdpFrame(data);

            return(frame);
        }
コード例 #8
0
        public UdpFrame ChangeFrameStatus(int packageID, UInt16 seq)
        {
            UdpPackage p = null;
            UdpFrame   f = null;

            lock (PackageList)
            {
                p = PackageList.FirstOrDefault(x => x.PackageID == packageID);

                if (p != null)
                {
                    f = p.FirstOrDefault(x => x.Seq == seq);

                    f.IsSended = true;
                }
            }

            return(f);
        }
コード例 #9
0
 /// <summary>
 /// 发送帧,帧不会重试,仅发送一次
 /// </summary>
 /// <param name="frame">数据帧</param>
 /// <param name="target">目标</param>
 protected virtual void SendFrame(UdpFrame frame, EndPoint target)
 {
     //直接发送帧命令
     InnerSendFrame(frame, target);
 }
コード例 #10
0
 protected virtual void ReceivedFeedback(UdpFrame frame)
 {
     Sender.ReceivedFeedback(frame);
 }
コード例 #11
0
        protected virtual void receiveProc(IAsyncResult result)
        {
            IPEndPoint ep     = new IPEndPoint(IPAddress.Any, 0);
            UdpClient  client = result.AsyncState as UdpClient;

            byte[] data = null;
            if (client == null)
            {
                Logger.Trace("退出接收0");
                return;
            }
            try
            {
                data = client.EndReceive(result, ref ep);
            }
            catch (SocketException e)
            {
                Logger.Debug("接收数据异常:\r\n{0}", e.ToString());
                beginReceive(client);
                //OnReceiveError(e);
                //isReceiving = false;
                return;
            }
            catch (ObjectDisposedException e)
            {
                Logger.Trace("退出接收1");
                Client = null;
                return;
            }
            catch (NullReferenceException e)
            {
                Logger.Trace("退出接收2");
                Client = null;
                return;
            }
            if (data == null && isReceiving)
            {
                beginReceive(client);
                return;
            }
            if (!isReceiving)
            {
                Logger.Trace("退出接收3");
                return;
            }

            byte[] rdata = new byte[data.Length];
            Buffer.BlockCopy(data, 0, rdata, 0, data.Length);
            UdpClient c = Client;

            if (isReceiving && c != null)
            {
                beginReceive(c);
            }

            UdpFrame frame = InnerReceivedFrameData(rdata, ep);

            if (frame != null)
            {
                if (frame.Command == UdpCommand.Data || frame.Command == UdpCommand.Text)
                {
                    UdpFrame confirm = new UdpFrame(frame.PackageSeq, frame.Seq, frame.Length, UdpCommand.Confirm, null, frame.ProxyID);
                    InnerSendFrame(confirm, ep);
                    // ILogger l = LoggerManager.GetLogger("R_" + frame.PackageSeq.ToString());
                    //  l.Trace(String.Format("收到数据帧:{0} {1} {2} ", frame.PackageSeq, frame.Seq, frame.Command));
                    lock (receivedCache)
                    {
                        // Logger.Trace(String.Format("收到数据帧:{0} {1} {2} ", frame.PackageSeq, frame.Seq, frame.Command));

                        //是否已经处理
                        UdpReceivedItem ignoreItem = processedPackage.FirstOrDefault(x => x.PackageSeq == frame.PackageSeq && x.Source.Address.Equals(ep.Address) && x.Source.Port == ep.Port && x.ProxyID == frame.ProxyID);
                        if (ignoreItem == null)
                        {
                            UdpReceivedItem rItem = receivedCache.FirstOrDefault(x => x.PackageSeq == frame.PackageSeq && x.Source.Address.Equals(ep.Address) && x.Source.Port == ep.Port && x.ProxyID == frame.ProxyID);
                            if (rItem == null)
                            {
                                rItem                  = new UdpReceivedItem();
                                rItem.Source           = ep;
                                rItem.ProxyID          = frame.ProxyID;
                                rItem.PackageSeq       = frame.PackageSeq;
                                rItem.Package          = new UdpPackage(frame.PackageSeq);
                                rItem.LastTime         = DateTime.Now;
                                rItem.Package.LastTime = DateTime.Now;
                                receivedCache.Add(rItem);
                            }

                            UdpFrame old = rItem.Package.FirstOrDefault(x => x.Seq == frame.Seq);
                            if (old == null)
                            {
                                rItem.Package.Add(frame);
                                rItem.Package.LastTime = DateTime.Now;
                                rItem.LastTime         = DateTime.Now;
                                if (frame.Length == rItem.Package.Count)
                                {
                                    //接收完成
                                    receivedCache.Remove(rItem);
                                    bool   isText      = rItem.Package.IsText();
                                    Byte[] packageData = rItem.Package.GetData();

                                    ThreadPool.QueueUserWorkItem(new WaitCallback((cr) =>
                                    {
                                        OnReceivedData(packageData, ep, rItem.ProxyID, isText);
                                    }));
                                    rItem.Package  = null;
                                    rItem.LastTime = DateTime.Now;
                                    processedPackage.Add(rItem);

                                    var rl = processedPackage.Where(x => (DateTime.Now - x.LastTime).TotalMilliseconds >= (SendTimeout.TotalMilliseconds * 3)).ToList();
                                    rl.ForEach(x => processedPackage.Remove(x));
                                }
                            }
                        }
                    }


                    //add  whb 2015-12-22 移除接收超时的包  防止缺损帧的包长期占用内存,导致内存不断上升的问题
                    //3分钟检查一次
                    if ((DateTime.Now - lastCheckReceivTimeoutTime).TotalMinutes >= 3)
                    {
                        lastCheckReceivTimeoutTime = DateTime.Now;
                        lock (receivedCache)
                        {
                            var removeList = receivedCache.Where(x => (DateTime.Now - x.LastTime) >= ReceiveTimeout).ToList();
                            removeList.ForEach(r =>
                            {
                                receivedCache.Remove(r);
                            });
                        }
                    }
                }
                else if (frame.Command == UdpCommand.Confirm)
                {
                    //lock (sendedList)
                    //{
                    //    sendedList.Add(frame);
                    //}
                    ReceivedFeedback(frame);
                }
            }
        }
コード例 #12
0
        protected override UdpFrame OnReceivedFrameData(byte[] data, System.Net.IPEndPoint ep)
        {
            if (data == null || data.Length < UdpFrame.HeadLength)
            {
                return(null);
            }

            UdpFrame frame = new UdpFrame(data);

            if (frame.Command == UdpCommand.Connect)
            {
                RemoveCachePackage(ep);
                ILogger l = LoggerManager.GetLogger(ep.Address.ToString() + "_" + ep.Port);
                l.Trace("收到连接命令:{0}", ep.ToString());
                //Logger.Trace("收到连接命令:{0}", ep.ToString());

                //连接成功
                UdpServerSession session = null;
                bool             isNew   = false;
                lock (clientList)
                {
                    session = clientList.FirstOrDefault(x => x.Target.Host == ep.Address.ToString() && ep.Port == x.Target.Port && x.ProxyID == frame.ProxyID);
                    if (session == null)
                    {
                        session = SessionFactory.CreateSession(null, new DnsEndPoint(ep.Address.ToString(), ep.Port)) as UdpServerSession;
                        // session = new UdpServerSession();
                        session.StartTime = DateTime.Now;
                        session.ProxyID   = frame.ProxyID;
                        //session.Target = new DnsEndPoint(ep.Address.ToString(), ep.Port);
                        session.Client     = new UdpServerSocketProxy(this, Client, session);
                        session.StartTime  = DateTime.Now;
                        session.ActiveTime = DateTime.Now;

                        clientList.Add(session);
                        isNew = true;
                        l.Trace("添加会话");
                    }
                    else
                    {
                        session.Client             = null;
                        session.ProxyID            = frame.ProxyID;
                        session.Target             = new DnsEndPoint(ep.Address.ToString(), ep.Port);
                        session.Client             = new UdpServerSocketProxy(this, Client, session);
                        session.Client.IsConnected = true;
                        l.Trace("更新会话");
                    }
                    if (isNew)
                    {
                        OnClientConnected(session);
                    }
                }
                UdpFrame ccFrame = new UdpFrame(0, 0, 0, UdpCommand.ConnectConfirm, null, frame.ProxyID);
                SendFrame(ccFrame, session.Target);
                return(null);
            }
            else if (frame.Command == UdpCommand.Close)
            {
                ILogger          l       = LoggerManager.GetLogger(ep.Address.ToString() + "_" + ep.Port);
                UdpServerSession session = getSession(ep.Address.ToString(), ep.Port, frame.ProxyID);
                if (session != null)
                {
                    session.Client.IsConnected = false;
                    l.Trace("收到回话关闭命令:{0}", session.Target);
                    RemoveSession(session);
                }
            }
            else if (frame.Command == UdpCommand.Pong)
            {
                List <UdpServerSession> sl = null;
                lock (clientList)
                {
                    sl = clientList.Where(x => x.Target.Host == ep.Address.ToString() && x.Target.Port == ep.Port).ToList();
                }
                sl.ForEach(s =>
                {
                    s.ActiveTime      = DateTime.Now;
                    s.LastReceiveTime = DateTime.Now;
                });
                //UdpServerSession session = getSession(ep.Address.ToString(), ep.Port, frame.ProxyID);
                //if (session != null)
                //{
                //    session.ActiveTime = DateTime.Now;
                //    session.LastReceiveTime = DateTime.Now;
                //}
            }
            else if (frame.Command == UdpCommand.Ping)
            {
                //UdpServerSession session = getSession(ep.Address.ToString(), ep.Port, frame.ProxyID);
                //if (session != null)
                //{
                //    Logger.Trace("收到Ping命令:{0}", session.Target);
                //    UdpFrame pong = new UdpFrame(0, 0, 0, UdpCommand.Pong, null, frame.ProxyID);
                //    SendFrame(pong, ep);

                //}

                UdpFrame pong = new UdpFrame(0, 0, 0, UdpCommand.Pong, null, frame.ProxyID);
                SendFrame(pong, ep);

                List <UdpServerSession> sl = null;
                lock (clientList)
                {
                    sl = clientList.Where(x => x.Target.Host == ep.Address.ToString() && x.Target.Port == ep.Port).ToList();
                }
                sl.ForEach(s =>
                {
                    s.ActiveTime      = DateTime.Now;
                    s.LastReceiveTime = DateTime.Now;
                });
            }


            return(frame);
        }
コード例 #13
0
        protected virtual void Close(bool isNotify, UInt16 proxyId)
        {
            if (proxyId == 0)
            {
                if (Interlocked.Exchange(ref mainCloseSignal, 1) == 1)
                {
                    return;
                }
                lock (timerLocker)
                {
                    if (checkTimer != null)
                    {
                        checkTimer.Dispose();
                        checkTimer = null;
                        Logger.Trace("关闭Ping");
                    }
                }

                List <UdpSession> sl = null;
                lock (proxySessionList)
                {
                    sl = proxySessionList.ToList();
                }
                sl.ForEach(s =>
                {
                    Close(isNotify, s.ProxyID);
                });
                if (RealTarget != null)
                {
                    RemoveCachePackage(RealTarget);
                }
            }

            if (isNotify)
            {
                UdpFrame frame = new UdpFrame(0, 0, 0, UdpCommand.Close, null, proxyId);
                try
                {
                    InnerSendFrame(frame, Target);
                }
                catch (SocketException)
                {
                }
            }
            if (Client != null && proxyId == 0)
            {
                Client.Close();
            }
            if (proxyId == 0)
            {
                bool oldConnected = IsConnected;
                IsConnected = false;

                StopReceive();
                StopSend();


                if (oldConnected)
                {
                    OnClosed();
                    Session.OnClosed();
                }

                Interlocked.Exchange(ref mainCloseSignal, 0);
            }
            else
            {
                UdpSession proxySession = null;
                lock (proxySessionList)
                {
                    proxySession = proxySessionList.FirstOrDefault(x => x.ProxyID == proxyId);
                    if (proxySession != null)
                    {
                        proxySessionList.Remove(proxySession);
                    }
                }
                if (proxySession != null)
                {
                    proxySession.OnClosed();
                }
            }
        }
コード例 #14
0
        protected bool ConnectedSync(UInt16 proxyId)
        {
            try
            {
                if (proxyId == 0)
                {
                    if (Client != null)
                    {
                        Close();
                    }

                    //Client = new System.Net.Sockets.UdpClient(Port);
                    //Client.DontFragment = true;

                    //Client.Client.ReceiveBufferSize = 1024 * 1024 * 2;
                    //Client.Client.SendBufferSize = 1024 * 1024 * 2;
                    Client = new UdpClient();
                    uint IOC_IN            = 0x80000000;
                    uint IOC_VENDOR        = 0x18000000;
                    uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
                    Client.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);

                    Client.Client.Bind(new IPEndPoint(IPAddress.Any, Port));
                    Client.Client.DontFragment      = true;
                    Client.Client.ReceiveBufferSize = 1024 * 1024 * 2;
                    Client.Client.SendBufferSize    = 1024 * 1024 * 2;

                    StartReceive();
                    StartSend();
                }

                Logger.Trace("发送连接请求:{0}", Target);
                UdpFrame frame = new UdpFrame(0, 0, 0, UdpCommand.Connect, null, proxyId);
                SendFrame(frame, Target);
                ManualResetEvent connWait = new System.Threading.ManualResetEvent(false);
                lock (connWaitList)
                {
                    connWaitList.Add(proxyId, connWait);
                }
                connWait.WaitOne(10000);

                lock (connWaitList)
                {
                    connWaitList.Remove(proxyId);
                }

                if (IsConnected && proxyId == 0)
                {
                    lock (timerLocker)
                    {
                        if (checkTimer == null)
                        {
                            checkTimer = new Timer(new TimerCallback(TimeoutCheck), null, checkTimeInterval, System.Threading.Timeout.Infinite);
                        }
                        else
                        {
                            checkTimer.Change(checkTimeInterval, System.Threading.Timeout.Infinite);
                        }
                    }
                    Logger.Trace("开启Ping");
                }
                else if (!IsConnected && proxyId == 0)
                {
                    if (Client != null)
                    {
                        Client.Close();
                    }
                    StopSend();
                    StopReceive();
                }


                return(IsConnected);
            }
            catch (Exception e)
            {
                Logger.Error("UdpSocketClient连接异常:\r\n{0}", e.ToString());
                if (proxyId == 0)
                {
                    if (IsSending)
                    {
                        StopSend();
                    }
                    if (IsReceiving)
                    {
                        StopReceive();
                    }
                }

                return(false);
            }
        }