using System; using System.Net.Sockets; using System.Threading; namespace Curtain.Net.Sockets.PLC { /// /// 扩展Socket,接收数据超时功能 /// internal static class TimeoutSocket //: Socket { //public TimeoutSocket(SocketInformation socketInformation) // :base(socketInformation) //{ //} //public TimeoutSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) // : base(addressFamily, socketType, protocolType) //{ //} /// /// 开始从连接的 System.Net.Sockets.Socket 中异步接收数据(超时后关闭连接的Socket)。 /// /// /// /// /// /// /// /// /// /// /// public static IAsyncResult BeginReceiveByTimeout(this Socket socket, byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, AsyncCallback timeoutCallback, int timeout, object state) { StateInfo stateInfo = new StateInfo(socket, callback, timeoutCallback, state); //IAsyncResult result = socket.BeginReceive(buffer, offset, size, socketFlags, ReceiveCallback, stateInfo); IAsyncResult result = socket.BeginReceive(buffer, offset, size, socketFlags, callback, state); stateInfo.Result = result; var registeredWaitHandle = ThreadPool.RegisterWaitForSingleObject( result.AsyncWaitHandle, WatchTimeOut, stateInfo, timeout, true); // stateInfo中保存RegisteredWaitHandle,以方便在WatchTimeOut // 中unregister. stateInfo.RegisteredWaitHandle = registeredWaitHandle; return result; } private static void WatchTimeOut(object state, bool timeout) { //Framework.Log.Logger.Debug("WatchTimeOut:timeout="+ timeout, "timeout"); if (state is StateInfo stateInfo) { // 设置的timeout前,操作未完成,则设置为操作Timeout if (timeout) { stateInfo.SetTimeout(); } // 取消之前注册的WaitOrTimerCallback stateInfo.RegisteredWaitHandle.Unregister( stateInfo.Result.AsyncWaitHandle); } } //private static void ReceiveCallback(IAsyncResult result) //{ // //if (result.AsyncState is StateInfo stateInfo) // //{ // // var count = stateInfo.Socket.EndReceive(stateInfo.Result); // // //stateInfo.SetResult(count); // //} //} } /// /// 异步接收数据,超时时回调事件状态 /// internal class StateInfo { /// /// 异步接收数据,超时时回调事件状态 /// public StateInfo(Socket socket, AsyncCallback cb, AsyncCallback tcb, object state) { Callback = cb; TimeoutCallback = tcb; this.Socket = socket; this.State = state; //this.AsycResult = result; } public Socket Socket { get; set; } public object State { get; set; } public AsyncCallback Callback { get; set; } public AsyncCallback TimeoutCallback { get; set; } public IAsyncResult Result { get; set; } public RegisteredWaitHandle RegisteredWaitHandle { get; set; } //public void SetResult(int count) //{ // this.IsCompleted = true; // this.ReceivedCount = count; // //this.m_waitHandle.Set(); // Callback?.Invoke(this); //} /// /// 超时后执行回调 /// public void SetTimeout() { TimeoutCallback?.Invoke(this.Result); } } /* public class AsyncResultTimeout : IAsyncResult { private ManualResetEvent m_waitHandle = new ManualResetEvent(false); public AsyncResultTimeout(Socket socket, object state) { this.Socket = socket; this.AsyncState = state; } #region IAsyncResult public object AsyncState { get; private set; } public WaitHandle AsyncWaitHandle { get; internal set; } public bool CompletedSynchronously { get { return false; } } public bool IsCompleted { get; private set; } #endregion public Socket Socket { get; private set; } } */ }