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); } } }
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; }
//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); }
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; } } }
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); } } } }
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); }
protected virtual UdpFrame OnReceivedFrameData(byte[] data, IPEndPoint ep) { if (data == null || data.Length < UdpFrame.HeadLength) { return(null); } UdpFrame frame = new UdpFrame(data); return(frame); }
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); }
/// <summary> /// 发送帧,帧不会重试,仅发送一次 /// </summary> /// <param name="frame">数据帧</param> /// <param name="target">目标</param> protected virtual void SendFrame(UdpFrame frame, EndPoint target) { //直接发送帧命令 InnerSendFrame(frame, target); }
protected virtual void ReceivedFeedback(UdpFrame frame) { Sender.ReceivedFeedback(frame); }
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); } } }
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); }
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(); } } }
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); } }