void ProcessReceive(SocketAsyncEventArgs se) { if (!Active) { ReleaseRecv(se, "!Active " + se.SocketError); return; } // 判断成功失败 if (se.SocketError != SocketError.Success) { // 未被关闭Socket时,可以继续使用 //if (!se.IsNotClosed()) if (OnReceiveError(se)) { var ex = se.GetException(); if (ex != null) { OnError("ReceiveAsync", ex); } ReleaseRecv(se, "SocketError " + se.SocketError); return; } } else { // 拷贝走数据,参数要重复利用 var data = se.Buffer.ReadBytes(se.Offset, se.BytesTransferred); var ep = se.RemoteEndPoint as IPEndPoint; // 在用户线程池里面去处理数据 //Task.Factory.StartNew(() => OnReceive(data, ep)).LogException(ex => OnError("OnReceive", ex)); //ThreadPool.QueueUserWorkItem(s => OnReceive(data, ep)); // 根据不信任用户原则,这里另外开线程执行用户逻辑 ThreadPool.UnsafeQueueUserWorkItem(s => { try { OnReceive(data, ep); } catch (Exception ex) { if (!ex.IsDisposed()) { OnError("OnReceive", ex); } } }, null); //// 直接在IO线程调用业务逻辑 //try //{ // // 估算完成时间,执行过长时提示 // using (var tc = new TimeCost("{0}.OnReceive".F(GetType().Name), 1000)) // { // tc.Log = Log; // OnReceive(data, ep); // } //} //catch (Exception ex) //{ // if (!ex.IsDisposed()) OnError("OnReceive", ex); //} } // 开始新的监听 if (Active && !Disposed) { ReceiveAsync(se, true); } else { ReleaseRecv(se, "!Active || Disposed"); } }
/// <summary>同步或异步收到数据</summary> /// <param name="se"></param> void ProcessEvent(SocketAsyncEventArgs se) { try { if (!Active) { ReleaseRecv(se, "!Active " + se.SocketError); return; } // 判断成功失败 if (se.SocketError != SocketError.Success) { // 未被关闭Socket时,可以继续使用 if (OnReceiveError(se)) { var ex = se.GetException(); if (ex != null) { OnError("ReceiveAsync", ex); } ReleaseRecv(se, "SocketError " + se.SocketError); return; } } else { var ep = se.RemoteEndPoint as IPEndPoint ?? Remote.EndPoint; var pk = new Packet(se.Buffer, se.Offset, se.BytesTransferred); if (ProcessAsync) { // 拷贝走数据,参数要重复利用 pk = pk.Clone(); // 根据不信任用户原则,这里另外开线程执行用户逻辑 // 有些用户在处理数据时,又发送数据并等待响应 ThreadPoolX.QueueUserWorkItem(() => ProcessReceive(pk, ep)); } else { // 同步执行,直接使用数据,不需要拷贝 // 直接在IO线程调用业务逻辑 ProcessReceive(pk, ep); } } // 开始新的监听 if (Active && !Disposed) { ReceiveAsync(se, true); } else { ReleaseRecv(se, "!Active || Disposed"); } } catch (Exception ex) { XTrace.WriteException(ex); } }
/// <summary>同步或异步收到数据</summary> /// <remarks> /// ioThread: /// 如果在StartReceive的时候线程池调用ProcessEvent,则处于worker线程; /// 如果在IOCP的时候调用ProcessEvent,则处于completionPort线程。 /// </remarks> /// <param name="se"></param> /// <param name="bytes"></param> /// <param name="ioThread">是否在IO线程池里面</param> internal protected void ProcessEvent(SocketAsyncEventArgs se, Int32 bytes, Boolean ioThread) { try { if (!Active) { ReleaseRecv(se, "!Active " + se.SocketError); return; } // 判断成功失败 if (se.SocketError != SocketError.Success) { // 未被关闭Socket时,可以继续使用 if (OnReceiveError(se)) { var ex = se.GetException(); if (ex != null) { OnError("ReceiveAsync", ex); } ReleaseRecv(se, "SocketError " + se.SocketError); return; } } else { var ep = se.RemoteEndPoint as IPEndPoint ?? Remote.EndPoint; if (bytes < 0) { bytes = se.BytesTransferred; } var pk = new Packet(se.Buffer, se.Offset, bytes); // 同步执行,直接使用数据,不需要拷贝 // 直接在IO线程调用业务逻辑 ProcessReceive(pk, ep); } // 开始新的监听 if (Active && !Disposed) { StartReceive(se, ioThread); } else { ReleaseRecv(se, "!Active || Disposed"); } } catch (Exception ex) { XTrace.WriteException(ex); // 如果数据处理异常,并且Error处理也抛出异常,则这里可能出错,导致整个接收链毁掉。 // 但是这个可能性极低 ReleaseRecv(se, "ProcessEventError " + ex.Message); Close("ProcessEventError"); Dispose(); } }
void ProcessReceive(SocketAsyncEventArgs se) { if (!Active) { ReleaseRecv(se, "!Active " + se.SocketError); return; } // 判断成功失败 if (se.SocketError != SocketError.Success) { // 未被关闭Socket时,可以继续使用 //if (!se.IsNotClosed()) if (OnReceiveError(se)) { var ex = se.GetException(); if (ex != null) { OnError("ReceiveAsync", ex); } ReleaseRecv(se, "SocketError " + se.SocketError); return; } } else { var ep = se.RemoteEndPoint as IPEndPoint ?? Remote.EndPoint; if (Log.Enable && LogReceive) { WriteLog("Recv# [{0}]: {1}", se.BytesTransferred, se.Buffer.ToHex(se.Offset, Math.Min(se.BytesTransferred, 32))); } var pk = new Packet(se.Buffer, se.Offset, se.BytesTransferred); if (ProcessAsync) { // 拷贝走数据,参数要重复利用 pk = pk.Clone(); // 根据不信任用户原则,这里另外开线程执行用户逻辑 ThreadPool.UnsafeQueueUserWorkItem(s => ProcessReceive(pk, ep), null); } else { // 同步执行,直接使用数据,不需要拷贝 // 直接在IO线程调用业务逻辑 ProcessReceive(pk, ep); } } // 开始新的监听 if (Active && !Disposed) { ReceiveAsync(se, true); } else { ReleaseRecv(se, "!Active || Disposed"); } }