采用异步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; }
}

本文介绍了一种采用异步Socket进行数据发送的方法,并利用池技术管理SocketAsyncEventArgs对象,以提高资源利用率和发送效率。文章详细展示了如何初始化、租赁及归还池中的对象。

2782

被折叠的 条评论
为什么被折叠?



