C#实现异步阻塞TCP(SocketAsyncEventArgs,SendAsync,ReceiveAsync,AcceptAsync,ConnectAsync)...

本文介绍了C#中利用SocketAsyncEventArgs实现异步阻塞的TCP通信,涵盖BufferManager内存管理、SocketAsyncEventArgsPool池化、AsyncUserToken令牌、TcpServiceSocketAsync服务器和TcpClientSocketAsync客户端的详细使用方法。文章还提供了服务器端和客户端的使用示例。
摘要由CSDN通过智能技术生成

1.类

(1)socket IO操作内存管理类 BufferManager

    // This class creates a single large buffer which can be divided up 
    // and assigned to SocketAsyncEventArgs objects for use with each 
    // socket I/O operation.  
    // This enables bufffers to be easily reused and guards against 
    // fragmenting heap memory.
    // 
    // The operations exposed on the BufferManager class are not thread safe.
    public class BufferManager
    {
        //buffer缓冲区大小
        private int m_numBytes;
        //缓冲区
        private byte[] m_buffer;
        private Stack<int> m_freeIndexPool;
        private int m_currentIndex;
        private int m_bufferSize;

        public BufferManager(int totalBytes, int bufferSize)
        {
            m_numBytes = totalBytes;
            m_currentIndex = 0;
            m_bufferSize = bufferSize;
            m_freeIndexPool = new Stack<int>();
        }

        /// <summary>
        /// 给buffer分配缓冲区
        /// </summary>
        public void InitBuffer()
        {
            m_buffer = new byte[m_numBytes];
        }

        /// <summary>
        ///  将buffer添加到args的IO缓冲区中,并设置offset
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool SetBuffer(SocketAsyncEventArgs args)
        {
            if (m_freeIndexPool.Count > 0)
            {
                args.SetBuffer(m_buffer, m_freeIndexPool.Pop(), m_bufferSize);
            }
            else
            {
                if ((m_numBytes - m_bufferSize) < m_currentIndex)
                {
                    return false;
                }
                args.SetBuffer(m_buffer, m_currentIndex, m_bufferSize);
                m_currentIndex += m_bufferSize;
            }
            return true;
        }

        /// <summary>
        /// 将buffer从args的IO缓冲区中释放
        /// </summary>
        /// <param name="args"></param>
        public void FreeBuffer(SocketAsyncEventArgs args)
        {
            m_freeIndexPool.Push(args.Offset);
            args.SetBuffer(null, 0, 0);
        }

        /// <summary>
        /// 释放全部buffer缓存
        /// </summary>
        public void FreeAllBuffer()
        {
            m_freeIndexPool.Clear();
            m_currentIndex = 0;
            m_buffer = null;
        }
    }

  

(2)SocketAsyncEventArgsPool

    // Represents a collection of reusable SocketAsyncEventArgs objects.  
    public class SocketAsyncEventArgsPool
    {
        private Stack<SocketAsyncEventArgs> m_pool;

        // Initializes the object pool to the specified size
        //
        // The "capacity" parameter is the maximum number of 
        // SocketAsyncEventArgs objects the pool can hold
        public SocketAsyncEventArgsPool(int capacity)
        {
            m_pool = new Stack<SocketAsyncEventArgs>(capacity);
        }

        // Add a SocketAsyncEventArg instance to the pool
        //
        //The "item" parameter is the SocketAsyncEventArgs instance 
        // to add to the pool
        public void Push(SocketAsyncEventArgs item)
        {
            if (item == null) { throw new ArgumentNullException("Items added to a SocketAsyncEventArgsPool cannot be null"); }
            lock (m_pool)
            {
                m_pool.Push(item);
            }
        }

        // Removes a SocketAsyncEventArgs instance from the pool
        // and returns the object removed from the pool
        public SocketAsyncEventArgs Pop()
        {
            lock (m_pool)
            {
                return m_pool.Pop();
            }
        }

        /// <summary>
        /// 清空栈中元素
        /// </summary>
        public void Clear()
        {
            lock (m_pool)
            {
                m_pool.Clear();
            }
        }

        // The number of SocketAsyncEventArgs instances in the pool
        public int Count
        {
            get { return m_pool.Count; }
        }

    }

  

(3)AsyncUserToken

    public class AsyncUserToken
    {
        private Socket socket = null;
        public Socket Socket { get => socket; set => socket = value; }
    }

  

(4)服务器端操作类TcpServiceSocketAsync

    public class TcpServiceSocketAsync
    {
        //接收数据事件
        public Action<string> recvMessageEvent = null;
        //发送结果事件
        public Action<int> sendResultEvent = null;

        //监听socket
        private Socket listenSocket = null;
        //允许连接到tcp服务器的tcp客户端数量
        private int numConnections = 0;
        //用于socket发送和接受的缓存区大小
        private int bufferSize = 0;
        //socket缓冲区管理对象
        private BufferManager bufferManager = null;
        //SocketAsyncEventArgs池
        private SocketAsyncEventArgsPool socketAsyncEventArgsPool = null;
        //当前连接的tcp客户端数量
        pr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值