採用異步Socket發送時,對於對像的回收使用了池技術
/// <summary>
/// 用於輔助異步發送Socket的幫肋類
/// </summary>
public class AsyncSocketSendHelper
{
#region 客戶端聯接池
/// <summary>
/// 接收SAEA池集合
/// </summary>
private ConcurrentStack<SocketAsyncEventArgs> ReceiveSocketArgsPool = new ConcurrentStack<SocketAsyncEventArgs>();
/// <summary>
/// 初始化接收socketargs對象池
/// </summary>
protected void InitReceiveSocketArgsPool()
{
for (int ndx = 0; ndx < 3000 ; ndx++)
{
ReceiveSocketArgsPool.Push(CreateReceiveSocketArgs());
}
}
/// <summary>
/// 創建一個接收SAEA對象,設置最大接收字節數
/// </summary>
/// <returns></returns>
protected virtual SocketAsyncEventArgs CreateReceiveSocketArgs()
{
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
e.Completed += IO_SendComleted;
return e;
}
/// <summary>
/// 租賃一個接收SAEA對象
/// </summary>
/// <returns></returns>
protected virtual SocketAsyncEventArgs RentReveiveSocketArgs()
{
SocketAsyncEventArgs e;
return ReceiveSocketArgsPool.TryPop(out e) ? e : CreateReceiveSocketArgs();
}
/// <summary>
/// 歸還一個接收SAEA參數
/// </summary>
/// <param name="e">還池</param>
protected virtual void GivebackReceiveSocketArgs(SocketAsyncEventArgs e)
{
if (e != null)
{
e.UserToken = null;
ReceiveSocketArgsPool.Push(e);
}
}
#endregion
/// <summary>
/// 發送數據服務
/// </summary>
/// <param name="socket">用於發送的Socket對像</param>
/// <param name="buff">需要發送的數據</param>
/// <param name="callBack">回調函數參數爲:發送結果,目標節點,發送數據</param>
/// <param name="userToken">用戶數據 </param>
/// <returns></returns>
public virtual void SendToAsync(Socket socket, byte[] buff, Action<AsyncSendResult> callBack = null, object userToken = null)
{
if (socket == null)
{
throw new NullReferenceException();
}
if (buff == null)
{
throw new NullReferenceException();
}
SocketAsyncEventArgs e = RentReveiveSocketArgs();
//設置發送緩衝區
e.SetBuffer(buff, 0, buff.Length);
try
{
//用戶標識
var token = new AsyncSendResult
{
Result = false,
RemoteEndPoint = socket.RemoteEndPoint.ToString(),
SendTime = DateTime.Now,
SendData = buff,
ResultTime = DateTime.Now,
CallBakc = callBack,
UserToKen = userToken,
};
e.UserToken = token;
//發送數據
if (!socket.SendAsync(e))
{
IO_SendComleted(socket, e);
}
}
catch (SocketException)
{
//還池
GivebackReceiveSocketArgs(e);
}
catch (ObjectDisposedException)
{
//還池
GivebackReceiveSocketArgs(e);
}
}
/// <summary>
/// 發送數據後的完成功能
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void IO_SendComleted(object sender, SocketAsyncEventArgs e)
{
try
{
if (e.UserToken != null)
{
AsyncSendResult token = e.UserToken as AsyncSendResult;
if (token != null)
{
//設置結果時間
token.ResultTime = DateTime.Now;
//發送數據OK
if (e.SocketError == SocketError.Success)
{
token.Result = true;
if (token.CallBakc != null)
{
token.CallBakc(token);
}
}
else
{
//發送數據失敗
token.Result = false;
if (token.CallBakc != null)
{
token.CallBakc(token);
}
}
}
}
}
finally
{
//還池
GivebackReceiveSocketArgs(e);
}
}
}
/// <summary>
/// 異步發送結果
/// </summary>
public class AsyncSendResult
{
/// <summary>
/// 結果
/// </summary>
public bool Result { get; set; }
/// <summary>
/// 目標節點
/// </summary>
public string RemoteEndPoint { get; set; }
/// <summary>
/// 發送數據
/// </summary>
public byte[] SendData { get; set; }
/// <summary>
/// 發送時間
/// </summary>
public DateTime SendTime { get; set; }
/// <summary>
/// 結果返回時間
/// </summary>
public DateTime ResultTime { get; set; }
/// <summary>
/// 獲取或設置與此操作關聯的用戶或應用程序對象。
/// </summary>
public object UserToKen { get; set; }
/// <summary>
/// 用於回調的委託
/// </summary>
internal Action<AsyncSendResult> CallBakc { get; set; }
}