/// <summary> /// 开始异步接收,同时处理传入的事件参数,里面可能有接收到的数据 /// </summary> /// <param name="e"></param> internal new void ReceiveAsync(DME_NetEventArgs e) { if (e.BytesTransferred > 0) OnReceive(e); else base.ReceiveAsync(e); }
void server_Accepted(object sender, DME_NetEventArgs e) { DME_TcpClient session = e.UserToken as DME_TcpClient; if (session == null) return; //session.NoDelay = false; SetEvent(session); }
/// <summary> /// 接受连接时 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void OnAccepted(Object sender, DME_NetEventArgs e) { DME_TcpClient session = e.UserToken as DME_TcpClient; if (session == null) return; session.Received += OnReceived; session.Error += new EventHandler<DME_NetEventArgs>(OnError); }
/// <summary> /// 异步接收 /// </summary> /// <param name="e"></param> protected override void ReceiveAsync(DME_NetEventArgs e) { if (!Client.IsBound) Bind(); // 如果没有传入网络事件参数,从对象池借用 if (e == null) e = Pop(); e.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); if (!Client.ReceiveFromAsync(e)) RaiseCompleteAsync(e); }
/// <summary> /// 接收数据。已重载。接收到0字节表示连接断开! /// </summary> /// <param name="e"></param> protected override void OnReceive(DME_NetEventArgs e) { if (e.BytesTransferred > 0) base.OnReceive(e); else { //// 关闭前回收 //Push(e); //Close(); OnError(e, null); } }
/// <summary> /// 已重载。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected override void OnReceived(object sender, DME_NetEventArgs e) { if (e.BytesTransferred > 1024) { WriteLog("{0}的数据包大于1k,抛弃!", e.RemoteEndPoint); return; } //WriteLog("{0} {1}", e.RemoteEndPoint, Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred)); WriteLog("{0} [{1}] {2}", e.RemoteEndPoint, e.BytesTransferred, e.GetString()); if ((e.RemoteEndPoint as IPEndPoint).Address != IPAddress.Any) { DME_UdpServer us = sender as DME_UdpServer; us.Send(e.Buffer, e.Offset, e.BytesTransferred, e.RemoteEndPoint); // 这里发送完成后不需要关闭Socket,因为这是UdpServer的Socket } }
/// <summary> /// 已重载。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected override void OnReceived(object sender, DME_NetEventArgs e) { DME_TcpClient tc = sender as DME_TcpClient; try { if (e.BytesTransferred > 1024) { WriteLog("{0}的数据包大于1k,抛弃!", tc.RemoteEndPoint); } else { WriteLog("{0} [{1}] {2}", tc.RemoteEndPoint, e.BytesTransferred, e.GetString()); if (tc != null && tc.Client.Connected) tc.Send(e.Buffer, e.Offset, e.BytesTransferred); } } finally { tc.Close(); } }
/// <summary> /// 创建会话 /// </summary> /// <param name="e"></param> /// <returns></returns> protected virtual DME_TcpSession CreateSession(DME_NetEventArgs e) { DME_TcpSession session = new DME_TcpSession(); session.Socket = e.AcceptSocket; session.RemoteEndPoint = e.AcceptSocket.RemoteEndPoint as IPEndPoint; Sessions.Add(session); return session; }
/// <summary> /// 已重载。 /// </summary> /// <param name="e"></param> protected override void OnComplete(DME_NetEventArgs e) { switch (e.LastOperation) { case SocketAsyncOperation.Accept: break; case SocketAsyncOperation.Connect: break; case SocketAsyncOperation.Disconnect: break; case SocketAsyncOperation.None: break; case SocketAsyncOperation.Receive: case SocketAsyncOperation.ReceiveFrom: case SocketAsyncOperation.ReceiveMessageFrom: OnReceive(e); return; case SocketAsyncOperation.Send: break; case SocketAsyncOperation.SendPackets: break; case SocketAsyncOperation.SendTo: break; default: break; } base.OnComplete(e); }
/// <summary> /// 在线程池里面执行指定委托。内部会处理异常并调用OnError /// </summary> /// <param name="callback"></param> /// <param name="e"></param> protected void ThreadPoolCallback(Action<DME_NetEventArgs> callback, DME_NetEventArgs e) { if (UseThreadPool) { ThreadPool.QueueUserWorkItem(delegate(Object state) { try { callback(state as DME_NetEventArgs); } catch (Exception ex) { try { OnError(state as DME_NetEventArgs, ex); } catch { } // 都是在线程池线程里面了,不要往外抛出异常 //throw; } }, e); } else { callback(e); } }
/// <summary> /// 新客户端到达 /// </summary> /// <param name="e"></param> protected virtual void OnAccept(DME_NetEventArgs e) { // 再次开始 if (e.SocketError != SocketError.OperationAborted) StartAccept(); // Socket错误由各个处理器来处理 if (e.SocketError != SocketError.Success) { OnError(e, null); return; } // 建立会话 DME_TcpSession session = CreateSession(e); session.NoDelay = this.NoDelay; e.UserToken = session; if (Accepted != null) Accepted(this, e); if (session.Socket != null && session.Socket.Connected) session.ReceiveAsync(e); }
/// <summary> /// 收到数据时 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void OnReceived(Object sender, DME_NetEventArgs e) { }
/// <summary> /// 异步触发完成事件处理程序 /// </summary> /// <param name="e"></param> protected void RaiseCompleteAsync(DME_NetEventArgs e) { if (UseThreadPool) { ThreadPool.QueueUserWorkItem(delegate(Object state) { RaiseComplete(state as DME_NetEventArgs); }, e); } else { RaiseComplete(e); } }
/// <summary> /// 错误发生时。负责调用Error事件以及回收网络事件参数 /// </summary> /// <remarks>OnError除了会调用ProcessError外,还会关闭Socket</remarks> /// <param name="e"></param> /// <param name="ex"></param> protected virtual void OnError(DME_NetEventArgs e, Exception ex) { try { ProcessError(e, ex); } finally { Close(); } }
/// <summary> /// 处理接收 /// </summary> /// <param name="e"></param> private void ProcessReceive(DME_NetEventArgs e) { if (NoDelay) ReceiveAsync(); if (Received != null) Received(this, e); if (NoDelay) Push(e); else ReceiveAsync(e); }
/// <summary> /// 把对象归还到池里 /// </summary> /// <remarks> /// 网络事件参数使用原则: /// 1,得到者负责回收(通过方法参数得到) /// 2,正常执行时自己负责回收,异常时顶级负责回收 /// 3,把回收责任交给别的方法 /// </remarks> /// <param name="e"></param> public void Push(DME_NetEventArgs e) { if (e == null) return; if (!e.Used) throw new Exception("准备回炉,怎么可能已经不再使用呢?"); e.UserToken = null; e.AcceptSocket = null; e.Completed -= OnCompleted; e.Used = false; Pool.Push(e); }
/// <summary> /// 接收到数据时 /// </summary> /// <param name="e"></param> protected virtual void OnReceive(DME_NetEventArgs e) { // Socket错误由各个处理器来处理 if (e.SocketError == SocketError.OperationAborted) { OnError(e, null); return; } // 没有接收事件时,马上开始处理重建委托 if (Received == null) { ReceiveAsync(e); return; } //ProcessReceive(e); // 这里可以改造为使用多线程处理事件 ThreadPoolCallback(ProcessReceive, e); }
/// <summary> /// 断开连接/发生错误 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void OnError(object sender, DME_NetEventArgs e) { if (e.SocketError != SocketError.Success || e.UserToken is Exception) WriteLog("{2}错误 {0} {1}", e.SocketError, e.UserToken as Exception, e.LastOperation); else WriteLog("{0}断开!", e.LastOperation); }
/// <summary> /// 已重载。服务器不会因为普通错误而关闭Socket停止服务 /// </summary> /// <param name="e"></param> /// <param name="ex"></param> protected override void OnError(DME_NetEventArgs e, Exception ex) { //base.OnError(e, ex); try { ProcessError(e, ex); } finally { if (e.SocketError == SocketError.OperationAborted) Close(); } }
/// <summary> /// 已重载。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected override void OnReceived(object sender, DME_NetEventArgs e) { if (e.BytesTransferred > 0) DME_StreamHandlerFactory.Process(StreamHandlerFactoryName, e.GetStream()); }
/// <summary> /// 接收到数据时 /// </summary> /// <remarks> /// 网络事件参数使用原则: /// 1,得到者负责回收(通过方法参数得到) /// 2,正常执行时自己负责回收,异常时顶级负责回收 /// 3,把回收责任交给别的方法 /// </remarks> /// <param name="e"></param> protected virtual void OnReceive(DME_NetEventArgs e) { // Socket错误由各个处理器来处理 if (e.SocketError != SocketError.Success) { OnError(e, null); return; } // 没有接收事件时,马上开始处理重建委托 if (Received == null) { // 3,把回收责任交给别的方法 ReceiveAsync(e); return; } //ProcessReceive(e); // 这里可以改造为使用多线程处理事件 // 3,把回收责任交给别的方法 ThreadPoolCallback(ProcessReceive, e); }
/// <summary> /// 错误发生/断开连接时。拦截Error事件中的所有异常,不外抛,防止因为Error异常导致多次调用OnError /// </summary> /// <param name="e"></param> /// <param name="ex"></param> protected void ProcessError(DME_NetEventArgs e, Exception ex) { if (Error != null) { if (ex != null) { if (e == null) e = Pop(); e.UserToken = ex; } try { Error(this, e); } catch (Exception ex2) { WriteLog(ex2.ToString()); } } // 不管有没有外部事件,都要归还网络事件参数,那是对象池的东西,不是你的 if (e != null) Push(e); }
/// <summary> /// 开始异步接收数据 /// </summary> /// <param name="e"></param> protected virtual void ReceiveAsync(DME_NetEventArgs e) { if (!Client.IsBound) Bind(); // 如果没有传入网络事件参数,从对象池借用 if (e == null) e = Pop(); if (!Client.ReceiveAsync(e)) RaiseCompleteAsync(e); }
/// <summary> /// 触发完成事件。 /// 可能由工作线程(事件触发)调用,也可能由用户线程通过线程池线程调用。 /// 作为顶级,将会处理所有异常并调用OnError,其中OnError有能力回收参数e。 /// </summary> /// <param name="e"></param> protected void RaiseComplete(DME_NetEventArgs e) { try { if (Completed != null) Completed(this, e); OnComplete(e); // 这里可以改造为使用多线程处理事件 //ThreadPoolCallback(OnCompleted, e); } catch (Exception ex) { OnError(e, ex); // 都是在线程池线程里面了,不要往外抛出异常 //throw; } }
/// <summary> /// 完成事件分发中心。 /// 正常执行时OnComplete必须保证回收参数e,异常时RaiseComplete将能够代为回收 /// </summary> /// <param name="e"></param> protected virtual void OnComplete(DME_NetEventArgs e) { }
/// <summary> /// 处理接收 /// </summary> /// <param name="e"></param> private void ProcessReceive(DME_NetEventArgs e) { if (NoDelay && e.SocketError != SocketError.OperationAborted) ReceiveAsync(); try { // Socket错误由各个处理器来处理 if (e.SocketError != SocketError.Success) { OnError(e, null); // OnError里面已经被回收,赋值为null,否则后面finally里面的Push会出错 e = null; return; } if (Received != null) Received(this, e); } finally { if (NoDelay) Push(e); else ReceiveAsync(e); } }