using System.Net; using System; using System.Net.Sockets; using System.Threading; namespace IFramework.Net.Udp { internal class SocketSend : UdpSocket,IDisposable { #region variable private int maxCount = 0; private SocketTokenManager sendTokenManager = null; private SocketBufferManager sendBufferManager = null; private bool _isDisposed = false; #endregion #region structure /// /// 发送事件回调 /// public event EventHandler SentEventHandler; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool isDisposing) { if (_isDisposed) return; if (isDisposing) { DisposeSocketPool(); socket.Dispose(); sendBufferManager.Clear(); _isDisposed = true; } } #endregion #region public method /// /// 初始化发送对象 /// /// 客户端最大数 public SocketSend(int maxCountClient, int blockSize = 4096) : base(blockSize) { this.maxCount = maxCountClient; socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket.ReceiveTimeout = receiveTimeout; socket.SendTimeout = sendTimeout; sendTokenManager = new SocketTokenManager(maxCountClient); sendBufferManager = new SocketBufferManager(maxCountClient, blockSize); for (int i = 0; i < maxCount; ++i) { SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs { UserToken = socket }; socketArgs.Completed += ClientSocket_Completed; sendBufferManager.SetBuffer(socketArgs); sendTokenManager.Set(socketArgs); } } public SocketSend(Socket socket, int maxCountClient, int blockSize = 4096) : base(blockSize) { this.maxCount = maxCountClient; base.socket = socket; sendTokenManager = new SocketTokenManager(maxCountClient); sendBufferManager = new SocketBufferManager(maxCountClient, blockSize); for (int i = 0; i < maxCount; ++i) { SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs { UserToken = base.socket }; socketArgs.Completed += ClientSocket_Completed; sendBufferManager.SetBuffer(socketArgs); sendTokenManager.Set(socketArgs); } } /// /// 发送数据 /// /// /// /// /// /// public bool Send(SegmentOffset dataSegment, IPEndPoint remoteEP, bool waiting) { try { bool isWillEvent = true; ArraySegment[] segItems = sendBufferManager.BufferToSegments(dataSegment.buffer, dataSegment.offset, dataSegment.size); foreach (var seg in segItems) { var tArgs = sendTokenManager.GetEmptyWait((retry) => { return true; }, waiting); if (tArgs == null) throw new Exception("发送缓冲池已用完,等待回收超时..."); tArgs.RemoteEndPoint = remoteEP; if (!sendBufferManager.WriteBuffer(tArgs, seg.Array, seg.Offset, seg.Count)) { sendTokenManager.Set(tArgs); throw new Exception(string.Format("发送缓冲区溢出...buffer block max size:{0}", sendBufferManager.BlockSize)); } isWillEvent &= socket.SendToAsync(tArgs); if (!isWillEvent) { ProcessSent(tArgs); } Thread.Sleep(5); } return isWillEvent; } catch (Exception ex) { throw ex; } } /// /// 同步发送数据 /// /// /// /// /// /// public int SendSync(SegmentOffset dataSegment, IPEndPoint remoteEP) { return socket.SendTo(dataSegment.buffer, dataSegment.offset, dataSegment.size, SocketFlags.None, remoteEP); } #endregion #region private method /// /// 释放缓冲池 /// private void DisposeSocketPool() { sendTokenManager.ClearToCloseArgs(); } /// /// 处理发送的数据 /// /// private void ProcessSent(SocketAsyncEventArgs e) { sendTokenManager.Set(e); if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { if (SentEventHandler != null) { SentEventHandler(e.UserToken as Socket, e); } } } /// /// 完成发送事件 /// /// /// void ClientSocket_Completed(object sender, SocketAsyncEventArgs e) { switch (e.LastOperation) { case SocketAsyncOperation.SendTo: case SocketAsyncOperation.SendPackets: case SocketAsyncOperation.Send: ProcessSent(e); break; default: break; } } #endregion } }