/// <summary> /// 开启线程发送 /// 每次发送时调用 /// </summary> private void TaskSend() { if (!semaphore.WaitOne(100)) { return; } if (!queue.IsEmpty) { Task.Factory.StartNew(() => { AsyncUDPSendBuffer buffer = null; do { if (queue.TryDequeue(out buffer)) { socket.SendTo(buffer.Buffer, buffer.Offset, buffer.Length, SocketFlags.None, buffer.EndPoint); buffer.FreeDataCache(); buffer.Free(); if (buffer.Token != null) { AsyncUdpUserToken token = buffer.Token as AsyncUdpUserToken; if (null != token) { //外部缓存也释放 token.FreeCache(); } } } }while (!queue.IsEmpty); semaphore.Release(); }); } }
/// <summary> /// 清除 /// </summary> public void Clear() { AsyncUdp.FreeCache(); AsyncUdp.ListPack.Clear(); resetEvent.Set(); isClear = true; }
/// <summary> /// 数据分包;采用分包层缓存分包 /// 分包就不可能使用外部缓存 /// /// </summary> /// <param name="token"></param> public void SendPackage(AsyncUdpUserToken token) { //使用了分包缓存 int index = 0; if (token.Length == 0) { token.Length = token.Data.Length; } do { AsyncUdpUserToken userToken = DataPack.PackCacheUDP(token, ref index); Send(userToken, 2); } while (index < token.Length); token.FreeCache(); }
/// <summary> /// 发送完成处理 /// </summary> /// <param name="e"></param> private void ProcessSent(SocketAsyncEventArgs e) { if (e.UserToken == null) { //说明是直接发送或者不够缓存时新创建的 e.SetBuffer(null, 0, 0); e.Completed -= IO_Completed; } else { //来自外部缓存或者本层缓存 AsyncUdpUserToken token = e.UserToken as AsyncUdpUserToken; if (null != token) { //来自外部数据 if (token.UserInfo == "outcache") { token.FreeCache(); e.SetBuffer(null, 0, 0); e.Completed -= IO_Completed; } } //else //{ // //回收缓存;如果发送每次在获取,则要释放 // //如果发送时判断分配缓存了,这里就可以不回收 // if (IsFixCache) // { // bufferManager.FreeBuffer(e); // } // else // { // bufferManager.GetBuffer(e); // } //} } e.UserToken = null; pool.Push(e); }
/// <summary> /// 接收完成 /// </summary> /// <param name="seq"></param> public void Add(int seq) { lastTime = DateTime.Now; if (AsyncUdp.ListPack != null) { if (AsyncUdp.ListPack.Count > seq) { try { //ListPack没有同步 AsyncUdpUserToken current = AsyncUdp.ListPack[seq]; packageID = current.DataPackage.packageID; current.FreeCache(); AsyncUdp.ListPack[seq] = null; } catch (Exception ex) { } } } }
/// <summary> /// 按照协议分包组包发送 /// </summary> /// <param name="token"></param> public void SendProtol(AsyncUdpUserToken token) { //使用了分包缓存 int index = 0; if (token.Length == 0) { token.Length = token.Data.Length; } do { AsyncUdpUserToken userToken = DataPack.PackCacheUDPHead(token, ref index); userToken.Remote = token.Remote; Send(userToken, 2); if (token.ListPack != null) { token.ListPack.Add(userToken); } } while (index < token.Length); token.FreeCache(); }
/// <summary> /// 发送数据 /// </summary> /// <param name="token"></param> /// <param name="isCache"></param> public void SendPackage(AsyncUdpUserToken token, int isCache = 0) { /* * 说明,通信层的缓存不回收,其余的数据均回收 * 0.socketArgs.UserToken=null,直接设置buffer=null(标记UserToken=null) * 1.本层缓存,不回收buffer;(不做任何处理,每次有多个) * 2.外部缓存,回收直接设置buffer=null,同时回收使用缓存(每次只会有一个,直接回收) */ if (0 == isCache) { Send(token.Data, token.Remote, token.Offset, token.Length); } else if (1 == isCache) { //使用通信缓存分组发送; //只有这个分支会用到通信缓存 int index = token.Offset; byte[] sendBuffer = null; int Offset = 0; int len = 0; do { token.Socket = socket; token.UserInfo = "udpcache"; if (token.Length == 0) { token.Length = token.Data.Length; } //拷贝数据到本缓存 AsyncUDPSendBuffer buffer = uDPSendPool.Pop(); buffer.EndPoint = token.Remote; if (IsFixCache) { cacheManager.SetBuffer(out sendBuffer, out Offset); } else { cacheManager.GetBuffer(out sendBuffer); } if (cacheManager.BufferSize + index >= token.Length) { Array.Copy(token.Data, token.Offset + index, sendBuffer, Offset, cacheManager.BufferSize); index += cacheManager.BufferSize; len = cacheManager.BufferSize; // buffer.Offset = Offset; buffer.Length = len; buffer.BufferCache = cacheManager; buffer.IsFixCache = IsFixCache; } else { //不够缓存发送了 byte[] tmp = new byte[token.Length - index]; Array.Copy(token.Data, token.Offset + index, tmp, 0, tmp.Length); index += tmp.Length; len = tmp.Length; buffer.Length = len; buffer.Offset = 0; buffer.Buffer = tmp; } // //socket.SendTo(sendBuffer, Offset, len,SocketFlags.None,token.Remote); queue.Enqueue(buffer); } while (index < token.Length); token.FreeCache();//用完外部的了; } else if (2 == isCache) { token.UserInfo = "outcache"; if (token.Length == 0) { token.Length = token.Data.Length; } AsyncUDPSendBuffer buffer = uDPSendPool.Pop(); buffer.Buffer = token.Data; buffer.Offset = token.Offset; buffer.Length = token.Length; buffer.EndPoint = token.Remote; buffer.Token = token;//外部缓存发送完成释放 queue.Enqueue(buffer); //持续使用外部缓存发送,发送后要释放 } else { Console.WriteLine("isCache参数不正确"); } TaskSend(); }
/// <summary> /// 发送数据 /// </summary> /// <param name="token"></param> /// <param name="isCache"></param> public void SendPackage(AsyncUdpUserToken token, int isCache = 0) { /* * 说明,通信层的缓存不回收,其余的数据均回收 * 0.socketArgs.UserToken=null,直接设置buffer=null(标记UserToken=null) * 1.本层缓存,不回收buffer;(不做任何处理,每次有多个) * 2.外部缓存,回收直接设置buffer=null,同时回收使用缓存(每次只会有一个,直接回收) */ if (0 == isCache) { Send(token.Data, token.Remote, token.Offset, token.Length); } else if (1 == isCache) { //使用通信缓存分组发送; //只有这个分支会用到通信缓存 int index = token.Offset; do { SocketAsyncEventArgs socketArgs = pool.Pop(); socketArgs.RemoteEndPoint = token.Remote; socketArgs.UserToken = token; token.Socket = socket; token.UserInfo = "udpcache"; if (socketArgs.Buffer == null) { //没有分配缓存时才分配 if (IsFixCache) { bufferManager.SetBuffer(socketArgs); } else { bufferManager.GetBuffer(socketArgs); } socketArgs.Completed += IO_Completed; } if (token.Length == 0) { token.Length = token.Data.Length; } //拷贝数据到本缓存, if (socketArgs.Count + index >= token.Length) { Array.Copy(token.Data, token.Offset + index, socketArgs.Buffer, socketArgs.Offset, socketArgs.Count); index += socketArgs.Count; } else { //不够缓存发送了 byte[] tmp = new byte[token.Length - index]; Array.Copy(token.Data, token.Offset + index, tmp, 0, tmp.Length); index += tmp.Length; //先释放 if (socketArgs.Buffer != null) { //说明来自缓存 if (IsFixCache) { bufferManager.FreeBuffer(socketArgs); } else { bufferManager.FreePoolBuffer(socketArgs); } } else { //说明来自创建 socketArgs.SetBuffer(null, 0, 0); } socketArgs.SetBuffer(tmp, 0, tmp.Length); socketArgs.UserToken = null; } // if (socketArgs.RemoteEndPoint != null) { if (!socket.SendToAsync(socketArgs)) { ProcessSent(socketArgs); } } } while (index < token.Length); token.FreeCache();//用完外部的了; } else if (2 == isCache) { SocketAsyncEventArgs socketArgs = pool.Pop(); socketArgs.RemoteEndPoint = token.Remote; token.UserInfo = "outcache"; if (token.Length == 0) { token.Length = token.Data.Length; } if (socketArgs.Buffer != null) { if (IsFixCache) { bufferManager.FreeBuffer(socketArgs); } else { bufferManager.FreePoolBuffer(socketArgs); } socketArgs.SetBuffer(null, 0, 0); } else { socketArgs.Completed += IO_Completed; } //持续使用外部缓存发送,发送后要释放 socketArgs.UserToken = token; socketArgs.SetBuffer(token.Data, token.Offset, token.Length); if (socketArgs.RemoteEndPoint != null) { if (!socket.SendToAsync(socketArgs)) { ProcessSent(socketArgs); } } } else { Console.WriteLine("isCache参数不正确"); } }