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;
}
}
*/
}