UDP CLIENT

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Aes.UdpTester {
    public partial class Form1 : Form {
        private AesUdpClient _udpClient = new AesUdpClient("120.79.232.38", 12018, null);

        public Form1() {
            InitializeComponent();
            _udpClient.ReceiveData += _udpClient_ReceiveData;
            _udpClient.Start();
        }

        private List<byte[]> _dataRcv = new List<byte[]>();
        private void _udpClient_ReceiveData(object sender, ReceiveDataEventArgs e) {
            _dataRcv.Add(e.Data);
        }

        private void button1_Click(object sender, EventArgs e) {
            var txt = txt_Msg.Text.Trim();
            if (string.IsNullOrEmpty(txt)) return;

            var bytes = Encoding.UTF8.GetBytes(txt);

            _udpClient.SendBytes(bytes);
        }

        private void timer1_Tick(object sender, EventArgs e) {
            if (_dataRcv.Count == 0) return;

            _dataRcv.ForEach(a => {
                txt_Logs.AppendText($"[{DateTime.Now:HH:mm:ss fff}]RCV:{a.Length} bytes" + Environment.NewLine);
            });

            _dataRcv.Clear();
        }
    }

    public abstract class NetClientBase : INetClient {
        /// <summary>
        /// 连接的远程服务器Ip地址
        /// </summary>
        public string ServerIp { get; }

        /// <summary>
        /// 连接的远程服务器端口号
        /// </summary>
        public int ServerPort { get; }

        /// <summary>
        /// 网络状态
        /// </summary>
        public NetState State { get; protected set; }

        public abstract void SendBytes(byte[] bytes);

        /// <summary>
        /// 
        /// </summary>
        public BuffBlock Buffer { get; }

        /// <summary>
        /// 报文处理器
        /// </summary>
        public INetHandler Handler { get; }

        protected IPEndPoint Remote { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        protected NetClientBase(string ip, int port, INetHandler handler) {
            ServerIp = ip;
            ServerPort = port;
            Handler = handler;

            Remote = new IPEndPoint(IPAddress.Parse(ServerIp), ServerPort);
            Buffer = new BuffBlock();
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void Init() { }
    }

    public interface INetHandler {
        /// <summary>
        /// 处理接收到的报文
        /// </summary>
        int Handler(ArraySegment<byte> segment);

        /// <summary>
        /// 
        /// </summary>
        void HandleTryConnect();

        /// <summary>
        /// 
        /// </summary>
        void HandleConnectSuccess();

        /// <summary>
        /// 
        /// </summary>
        void HandleConnectFailure();

        /// <summary>
        /// 
        /// </summary>
        void HandleDisconnect();
    }

    /// <summary>
    /// 
    /// </summary>
    public class AesUdpClient : NetClientBase {
        //Sae池
        private static readonly SaeQueuePool _saeQueue = new SaeQueuePool(1024);
        private Socket _listen;
        private readonly int _bufferLength;

        /// <summary>
        ///     获取SEA池中的可用项数量
        /// </summary>
        public int SeaCount => _saeQueue.Count;

        /// <summary>
        ///     获取系统分配的UDP端口号
        /// </summary>
        public int LocalPort { get; private set; }

        /// <summary>
        /// </summary>
        public long ReceivedBytesCount { get; private set; }

        /// <summary>
        /// </summary>
        public long SendBytesCount { get; private set; }

        /// <summary>
        ///     收到的报文数量
        /// </summary>
        public uint ReceivedCount { get; private set; }

        /// <summary>
        ///     发送的报文数量
        /// </summary>
        public uint SendCount { get; private set; }

        /// <summary>
        /// </summary>
        public bool IsRunning { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        public AesUdpClient(string ip, int port, INetHandler handler) : base(ip, port, handler) {
            _bufferLength = 1024;
        }

        /// <summary>
        /// 
        /// </summary>
        public override void SendBytes(byte[] bytes) {
            if (!IsRunning || _listen == null)
                return;

            //优先从可复用队列中取
            var socketSendAsync = _saeQueue.Dequeue();
            socketSendAsync.SetBuffer(bytes, 0, bytes.Length);
            socketSendAsync.RemoteEndPoint = Remote;

            SendCount++;
            SendBytesCount += bytes.Length;

            //Counter.Udp_SendBytesCount += bytes.Length;
            //LogConsole.Debug($"[UDP]Send={bytes.ToHexString()}");

            //如果发送失败,则强制归队
            if (!_listen.SendToAsync(socketSendAsync))
                _saeQueue.Enqueue(socketSendAsync);
        }

        /// <summary>
        ///     收到数据事件
        /// </summary>
        public event EventHandler<ReceiveDataEventArgs> ReceiveData;

        /// <summary>
        ///     启动UPD监听,接收来自网络上的UDP消息
        /// </summary>
        public void Start() {
            _listen = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            _listen.Connect(Remote);

            //_listen.Bind(local);

            var socketAsync = new SocketAsyncEventArgs();
            socketAsync.SetBuffer(new byte[_bufferLength], 0, _bufferLength);
            socketAsync.Completed += SocketAsync_Completed;
            socketAsync.RemoteEndPoint = Remote;

            IsRunning = true;

            StartReceive(socketAsync);
        }


        /// <summary>
        /// </summary>
        public void Stop() {
            IsRunning = false;
            _listen?.Close();
            _listen = null;
        }

        /// <summary>
        ///     重置收发数据统计
        /// </summary>
        public void ResetSR() {
            ReceivedBytesCount = 0;
            SendBytesCount = 0;
            ReceivedCount = 0;
            SendCount = 0;
        }

        /// <summary>
        ///     开始异步接收UDP消息
        /// </summary>
        private void StartReceive(SocketAsyncEventArgs socketAsync) {
            if (!IsRunning) return;

            //https://docs.microsoft.com/zh-cn/dotnet/api/system.net.sockets.socket.receivefromasync?view=netframework-4.8
            //ReceiveFromAsync方法主要用于接收无连接套接字上的数据。 套接字的本地地址必须是已知的。
            //调用方必须将 SocketAsyncEventArgs.RemoteEndPoint 属性设置为从中 IPEndPoint 接收数据的远程主机的。
            //SocketAsyncEventArgs.SocketFlags参数上的属性为 e 窗口套接字服务提供程序提供有关读取请求的其他信息。
            //有关如何使用此参数的详细信息,请参阅 System.Net.Sockets.SocketFlags 。

            //如果 I/O 操作挂起,则为 true。 操作完成时,将引发 e 参数的 Completed 事件。
            //如果 I/ O 操作同步完成,则为 false。
            //在这种情况下,将不会引发 e 参数的 Completed 事件,并且可能在方法调用返回后立即检查作为参数传递的 e 对象以检索操作的结果。

            if (!_listen.ReceiveFromAsync(socketAsync))
                SocketAsync_Completed(_listen, socketAsync);
        }

        /// <summary>
        /// </summary>
        private void SocketAsync_Completed(object sender, SocketAsyncEventArgs e) {
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
                if (e.LastOperation == SocketAsyncOperation.ReceiveFrom) {
                    var data = new byte[e.BytesTransferred];
                    System.Buffer.BlockCopy(e.Buffer, e.Offset, data, 0, data.Length);

                    //LogConsole.Debug($"[UDP]Rcv:{data.ToHexString()},长度={data.Length}");

                    ReceivedBytesCount += e.BytesTransferred;
                    ReceivedCount++;

                    StartReceive(e);
                    OnReceive((IPEndPoint)e.RemoteEndPoint, data);
                    return;
                }

            StartReceive(e);
        }

        /// <summary>
        ///     远程端点收到消息处理
        /// </summary>
        private void OnReceive(IPEndPoint iPEndPoint, byte[] data) {
            if (!IsRunning) return;
            if (iPEndPoint == null || data == null || data.Length == 0) return;

            //Counter.Udp_RecvBytesCount += data.Length;

            //抛出收到数据事件
            ReceiveData?.Invoke(this, new ReceiveDataEventArgs {
                Data = data, IpEndPoint = iPEndPoint
            });



            return;
            if (data.Length < 8 + 4) {
                //TODO:执行缓冲
#if DEBUG
                //LogConsole.Debug($"[UDP]RCV={iPEndPoint.Address}报文过短,抛弃:" + data.ToHexString());
#endif
                return;
            }

            var i = 0;
            while (i < data.Length) {
                var prefix = data[i];
                if (prefix != 0x7E) {
#if DEBUG
                    //LogConsole.Debug($"[UDP]RCV={iPEndPoint.Address}报文首字错误,抛弃:" + data.ToHexString());
#endif
                    return;
                }

                var bodyLen = BitConverter.ToUInt16(data, i + 3);
                if (bodyLen <= 0) return;

                var len = 5 + bodyLen;
                var subfix = data[i + len - 1];
                if (subfix != 0x7F) {
#if DEBUG
                    //LogConsole.Debug($"[UDP]RCV={iPEndPoint.Address}报文尾字错误,抛弃:" + data.ToHexString());
#endif
                    return;
                }

                var d = new byte[len];
                Array.Copy(data, i, d, 0, len);

                //                _handlerQueue.Enqueue(new UdpRequestWrapper(d, iPEndPoint));
                //#if DEBUG
                //                if (Settings.DebugMode && Settings.DebugUdpPacket)
                //                    LogConsole.Debug($"[UDP]{iPEndPoint.Address}偏移={i},解析获得报文:{d.ToHexString()}");
                //#endif

                i += len;
            }
        }
    }

    /// <summary>
    ///     接收数据事件参数
    /// </summary>
    public class ReceiveDataEventArgs : EventArgs {
        /// <summary>
        ///     收到的数据
        /// </summary>
        public byte[] Data { get; set; }

        /// <summary>
        ///     发送数据的IP
        /// </summary>
        public IPEndPoint IpEndPoint { get; set; }
    }

    /// <summary>
    ///     SocketAsyncEventArgs可复用队列
    /// </summary>
    internal class SaeQueuePool {
        /// <summary>
        ///     SocketAsyncEventArgs可复用队列
        /// </summary>
        private readonly ConcurrentQueue<SocketAsyncEventArgs> _saeQueue;

        /// <summary>
        ///     构造函数
        /// </summary>
        public SaeQueuePool(int count) {
            _saeQueue = new ConcurrentQueue<SocketAsyncEventArgs>();
            for (var i = 0; i < count; i++) _saeQueue.Enqueue(new SocketAsyncEventArgs());
        }

        /// <summary>
        ///     获取队列中的数量
        /// </summary>
        public int Count => _saeQueue.Count;

        /// <summary>
        ///     取出项
        /// </summary>
        public SocketAsyncEventArgs Dequeue() {
            var success = _saeQueue.TryDequeue(out var item);
            if (!success)
                item = new SocketAsyncEventArgs();

            item.Completed += Item_Completed;
            return item;
        }

        /// <summary>
        /// </summary>
        private void Item_Completed(object sender, SocketAsyncEventArgs e) {
            e.Completed -= Item_Completed;
            _saeQueue.Enqueue(e);
        }

        /// <summary>
        ///     退回项到池中
        /// </summary>
        public void Enqueue(SocketAsyncEventArgs sae) {
            sae.Completed -= Item_Completed;
            _saeQueue.Enqueue(sae);
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class BuffBlock {
        private readonly byte[] _buff;

        public int Size { get; }

        public int OffsetFree => Start + Count;

        /// <summary>
        /// 
        /// </summary>
        public int Count { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        public int Start { get; private set; }

        public BuffBlock(int size = 1024 * 20) {
            Size = size;
            _buff = new byte[Size];
        }

        public void Append(byte[] data, int offset, int count) {
            if (OffsetFree + count > Size)
                Recalc();

            try {
                Array.Copy(data, offset, _buff, OffsetFree, count);
                Count += count;
            }
            catch (Exception ex) {

            }
        }

        public void Take(int count) {
            if (count > Count)
                throw new ArgumentOutOfRangeException();

            Start += count;
            Count -= count;
        }

        private void Recalc() {
            if (Count == 0) {
                Start = 0;
                return;
            }

            Array.Copy(_buff, Start, _buff, 0, Count);
            Start = 0;
        }

        public ArraySegment<byte> GetBytes() {
            return new ArraySegment<byte>(_buff, Start, Count);
        }

        public void Clear() {
            Start = 0;
            Count = 0;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public interface INetClient {
        /// <summary>
        /// 
        /// </summary>
        string ServerIp { get; }

        /// <summary>
        /// 
        /// </summary>
        int ServerPort { get; }

        /// <summary>
        /// 
        /// </summary>
        NetState State { get; }

        /// <summary>
        /// 
        /// </summary>
        void SendBytes(byte[] bytes);
    }

    public interface ITcpNetClient : INetClient {
        /// <summary>
        /// 
        /// </summary>
        void TryConnectAsyn();

        /// <summary>
        /// 
        /// </summary>
        void DisConnect();
    }

    /// <summary>
    /// 
    /// </summary>
    public enum NetState {
        /// <summary>
        /// 未连接或已断线状态
        /// </summary>
        None,
        /// <summary>
        /// 正在连接,此时不允许再次发起连接动作
        /// </summary>
        Connectting,
        /// <summary>
        /// 正常工作状态
        /// </summary>
        Working,
    }
}

  

using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;
namespace Aes.UdpTester {    public partial class Form1 : Form {        private AesUdpClient _udpClient = new AesUdpClient("120.79.232.38", 12018, null);
        public Form1() {            InitializeComponent();            _udpClient.ReceiveData += _udpClient_ReceiveData;            _udpClient.Start();        }
        private List<byte[]> _dataRcv = new List<byte[]>();        private void _udpClient_ReceiveData(object sender, ReceiveDataEventArgs e) {            _dataRcv.Add(e.Data);        }
        private void button1_Click(object sender, EventArgs e) {            var txt = txt_Msg.Text.Trim();            if (string.IsNullOrEmpty(txt)) return;
            var bytes = Encoding.UTF8.GetBytes(txt);
            _udpClient.SendBytes(bytes);        }
        private void timer1_Tick(object sender, EventArgs e) {            if (_dataRcv.Count == 0) return;
            _dataRcv.ForEach(a => {                txt_Logs.AppendText($"[{DateTime.Now:HH:mm:ss fff}]RCV:{a.Length} bytes" + Environment.NewLine);            });
            _dataRcv.Clear();        }    }
    public abstract class NetClientBase : INetClient {        /// <summary>        /// 连接的远程服务器Ip地址        /// </summary>        public string ServerIp { get; }
        /// <summary>        /// 连接的远程服务器端口号        /// </summary>        public int ServerPort { get; }
        /// <summary>        /// 网络状态        /// </summary>        public NetState State { get; protected set; }
        public abstract void SendBytes(byte[] bytes);
        /// <summary>        ///         /// </summary>        public BuffBlock Buffer { get; }
        /// <summary>        /// 报文处理器        /// </summary>        public INetHandler Handler { get; }
        protected IPEndPoint Remote { get; private set; }
        /// <summary>        ///         /// </summary>        protected NetClientBase(string ip, int port, INetHandler handler) {            ServerIp = ip;            ServerPort = port;            Handler = handler;
            Remote = new IPEndPoint(IPAddress.Parse(ServerIp), ServerPort);            Buffer = new BuffBlock();        }
        /// <summary>        ///         /// </summary>        protected virtual void Init() { }    }
    public interface INetHandler {        /// <summary>        /// 处理接收到的报文        /// </summary>        int Handler(ArraySegment<byte> segment);
        /// <summary>        ///         /// </summary>        void HandleTryConnect();
        /// <summary>        ///         /// </summary>        void HandleConnectSuccess();
        /// <summary>        ///         /// </summary>        void HandleConnectFailure();
        /// <summary>        ///         /// </summary>        void HandleDisconnect();    }
    /// <summary>    ///     /// </summary>    public class AesUdpClient : NetClientBase {        //Sae池        private static readonly SaeQueuePool _saeQueue = new SaeQueuePool(1024);        private Socket _listen;        private readonly int _bufferLength;
        /// <summary>        ///     获取SEA池中的可用项数量        /// </summary>        public int SeaCount => _saeQueue.Count;
        /// <summary>        ///     获取系统分配的UDP端口号        /// </summary>        public int LocalPort { get; private set; }
        /// <summary>        /// </summary>        public long ReceivedBytesCount { get; private set; }
        /// <summary>        /// </summary>        public long SendBytesCount { get; private set; }
        /// <summary>        ///     收到的报文数量        /// </summary>        public uint ReceivedCount { get; private set; }
        /// <summary>        ///     发送的报文数量        /// </summary>        public uint SendCount { get; private set; }
        /// <summary>        /// </summary>        public bool IsRunning { get; private set; }
        /// <summary>        ///         /// </summary>        public AesUdpClient(string ip, int port, INetHandler handler) : base(ip, port, handler) {            _bufferLength = 1024;        }
        /// <summary>        ///         /// </summary>        public override void SendBytes(byte[] bytes) {            if (!IsRunning || _listen == null)                return;
            //优先从可复用队列中取            var socketSendAsync = _saeQueue.Dequeue();            socketSendAsync.SetBuffer(bytes, 0, bytes.Length);            socketSendAsync.RemoteEndPoint = Remote;
            SendCount++;            SendBytesCount += bytes.Length;
            //Counter.Udp_SendBytesCount += bytes.Length;            //LogConsole.Debug($"[UDP]Send={bytes.ToHexString()}");
            //如果发送失败,则强制归队            if (!_listen.SendToAsync(socketSendAsync))                _saeQueue.Enqueue(socketSendAsync);        }
        /// <summary>        ///     收到数据事件        /// </summary>        public event EventHandler<ReceiveDataEventArgs> ReceiveData;
        /// <summary>        ///     启动UPD监听,接收来自网络上的UDP消息        /// </summary>        public void Start() {            _listen = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);            _listen.Connect(Remote);
            //_listen.Bind(local);
            var socketAsync = new SocketAsyncEventArgs();            socketAsync.SetBuffer(new byte[_bufferLength], 0, _bufferLength);            socketAsync.Completed += SocketAsync_Completed;            socketAsync.RemoteEndPoint = Remote;
            IsRunning = true;
            StartReceive(socketAsync);        }

        /// <summary>        /// </summary>        public void Stop() {            IsRunning = false;            _listen?.Close();            _listen = null;        }
        /// <summary>        ///     重置收发数据统计        /// </summary>        public void ResetSR() {            ReceivedBytesCount = 0;            SendBytesCount = 0;            ReceivedCount = 0;            SendCount = 0;        }
        /// <summary>        ///     开始异步接收UDP消息        /// </summary>        private void StartReceive(SocketAsyncEventArgs socketAsync) {            if (!IsRunning) return;
            //https://docs.microsoft.com/zh-cn/dotnet/api/system.net.sockets.socket.receivefromasync?view=netframework-4.8            //ReceiveFromAsync方法主要用于接收无连接套接字上的数据。 套接字的本地地址必须是已知的。            //调用方必须将 SocketAsyncEventArgs.RemoteEndPoint 属性设置为从中 IPEndPoint 接收数据的远程主机的。            //SocketAsyncEventArgs.SocketFlags参数上的属性为 e 窗口套接字服务提供程序提供有关读取请求的其他信息。            //有关如何使用此参数的详细信息,请参阅 System.Net.Sockets.SocketFlags 。
            //如果 I/O 操作挂起,则为 true。 操作完成时,将引发 e 参数的 Completed 事件。            //如果 I/ O 操作同步完成,则为 false。            //在这种情况下,将不会引发 e 参数的 Completed 事件,并且可能在方法调用返回后立即检查作为参数传递的 e 对象以检索操作的结果。
            if (!_listen.ReceiveFromAsync(socketAsync))                SocketAsync_Completed(_listen, socketAsync);        }
        /// <summary>        /// </summary>        private void SocketAsync_Completed(object sender, SocketAsyncEventArgs e) {            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)                if (e.LastOperation == SocketAsyncOperation.ReceiveFrom) {                    var data = new byte[e.BytesTransferred];                    System.Buffer.BlockCopy(e.Buffer, e.Offset, data, 0, data.Length);
                    //LogConsole.Debug($"[UDP]Rcv:{data.ToHexString()},长度={data.Length}");
                    ReceivedBytesCount += e.BytesTransferred;                    ReceivedCount++;
                    StartReceive(e);                    OnReceive((IPEndPoint)e.RemoteEndPoint, data);                    return;                }
            StartReceive(e);        }
        /// <summary>        ///     远程端点收到消息处理        /// </summary>        private void OnReceive(IPEndPoint iPEndPoint, byte[] data) {            if (!IsRunning) return;            if (iPEndPoint == null || data == null || data.Length == 0) return;
            //Counter.Udp_RecvBytesCount += data.Length;
            //抛出收到数据事件            ReceiveData?.Invoke(this, new ReceiveDataEventArgs {                Data = data, IpEndPoint = iPEndPoint            });


            return;            if (data.Length < 8 + 4) {                //TODO:执行缓冲#if DEBUG                //LogConsole.Debug($"[UDP]RCV={iPEndPoint.Address}报文过短,抛弃:" + data.ToHexString());#endif                return;            }
            var i = 0;            while (i < data.Length) {                var prefix = data[i];                if (prefix != 0x7E) {#if DEBUG                    //LogConsole.Debug($"[UDP]RCV={iPEndPoint.Address}报文首字错误,抛弃:" + data.ToHexString());#endif                    return;                }
                var bodyLen = BitConverter.ToUInt16(data, i + 3);                if (bodyLen <= 0) return;
                var len = 5 + bodyLen;                var subfix = data[i + len - 1];                if (subfix != 0x7F) {#if DEBUG                    //LogConsole.Debug($"[UDP]RCV={iPEndPoint.Address}报文尾字错误,抛弃:" + data.ToHexString());#endif                    return;                }
                var d = new byte[len];                Array.Copy(data, i, d, 0, len);
                //                _handlerQueue.Enqueue(new UdpRequestWrapper(d, iPEndPoint));                //#if DEBUG                //                if (Settings.DebugMode && Settings.DebugUdpPacket)                //                    LogConsole.Debug($"[UDP]{iPEndPoint.Address}偏移={i},解析获得报文:{d.ToHexString()}");                //#endif
                i += len;            }        }    }
    /// <summary>    ///     接收数据事件参数    /// </summary>    public class ReceiveDataEventArgs : EventArgs {        /// <summary>        ///     收到的数据        /// </summary>        public byte[] Data { get; set; }
        /// <summary>        ///     发送数据的IP        /// </summary>        public IPEndPoint IpEndPoint { get; set; }    }
    /// <summary>    ///     SocketAsyncEventArgs可复用队列    /// </summary>    internal class SaeQueuePool {        /// <summary>        ///     SocketAsyncEventArgs可复用队列        /// </summary>        private readonly ConcurrentQueue<SocketAsyncEventArgs> _saeQueue;
        /// <summary>        ///     构造函数        /// </summary>        public SaeQueuePool(int count) {            _saeQueue = new ConcurrentQueue<SocketAsyncEventArgs>();            for (var i = 0; i < count; i++) _saeQueue.Enqueue(new SocketAsyncEventArgs());        }
        /// <summary>        ///     获取队列中的数量        /// </summary>        public int Count => _saeQueue.Count;
        /// <summary>        ///     取出项        /// </summary>        public SocketAsyncEventArgs Dequeue() {            var success = _saeQueue.TryDequeue(out var item);            if (!success)                item = new SocketAsyncEventArgs();
            item.Completed += Item_Completed;            return item;        }
        /// <summary>        /// </summary>        private void Item_Completed(object sender, SocketAsyncEventArgs e) {            e.Completed -= Item_Completed;            _saeQueue.Enqueue(e);        }
        /// <summary>        ///     退回项到池中        /// </summary>        public void Enqueue(SocketAsyncEventArgs sae) {            sae.Completed -= Item_Completed;            _saeQueue.Enqueue(sae);        }    }
    /// <summary>    ///     /// </summary>    public class BuffBlock {        private readonly byte[] _buff;
        public int Size { get; }
        public int OffsetFree => Start + Count;
        /// <summary>        ///         /// </summary>        public int Count { get; private set; }
        /// <summary>        ///         /// </summary>        public int Start { get; private set; }
        public BuffBlock(int size = 1024 * 20) {            Size = size;            _buff = new byte[Size];        }
        public void Append(byte[] data, int offset, int count) {            if (OffsetFree + count > Size)                Recalc();
            try {                Array.Copy(data, offset, _buff, OffsetFree, count);                Count += count;            }            catch (Exception ex) {
            }        }
        public void Take(int count) {            if (count > Count)                throw new ArgumentOutOfRangeException();
            Start += count;            Count -= count;        }
        private void Recalc() {            if (Count == 0) {                Start = 0;                return;            }
            Array.Copy(_buff, Start, _buff, 0, Count);            Start = 0;        }
        public ArraySegment<byte> GetBytes() {            return new ArraySegment<byte>(_buff, Start, Count);        }
        public void Clear() {            Start = 0;            Count = 0;        }    }
    /// <summary>    ///     /// </summary>    public interface INetClient {        /// <summary>        ///         /// </summary>        string ServerIp { get; }
        /// <summary>        ///         /// </summary>        int ServerPort { get; }
        /// <summary>        ///         /// </summary>        NetState State { get; }
        /// <summary>        ///         /// </summary>        void SendBytes(byte[] bytes);    }
    public interface ITcpNetClient : INetClient {        /// <summary>        ///         /// </summary>        void TryConnectAsyn();
        /// <summary>        ///         /// </summary>        void DisConnect();    }
    /// <summary>    ///     /// </summary>    public enum NetState {        /// <summary>        /// 未连接或已断线状态        /// </summary>        None,        /// <summary>        /// 正在连接,此时不允许再次发起连接动作        /// </summary>        Connectting,        /// <summary>        /// 正常工作状态        /// </summary>        Working,    }}

原文地址:https://www.cnblogs.com/anduinlothar/p/14632728.html