基于异步socket客户端接收数据基础类。

来源:互联网 发布:windows photos打不开 编辑:程序博客网 时间:2024/06/17 01:05

namespace SocketServer

{

 

    /// <summary>

    /// 组包基础类

    /// </summary>

    /// <typeparam name="T"></typeparam>

    public class GroupPackage<T> where T :  struct

    {

        //int m_nDataLen;

 

        int m_nRecvOffset; //接受偏移

        byte[] m_bRealData; //接收数据

        int m_nAllocRealDataItem; //默认长度

 

//包头

        public T Head { get; set; }

 

        public int HeadLen { get; set; }

 

        public GroupPackage(IntPtr handler)

        {

            OrgHandler = handler;

            HeadLen = Marshal.SizeOf(typeof(T));

            m_nAllocRealDataItem = 1024;

            m_bRealData = new byte[1024];

        }

 

 

        public void ClearRecvBuffer()

        {

            m_nRecvOffset = 0;

        }

        /// <summary>

        /// 传入的指针

        /// </summary>

        public IntPtr OrgHandler { get; set; }

 

        /// <summary>

        /// 指针

        /// </summary>

        public IntPtr Handler

        {

            get { return this.GetType().TypeHandle.Value; }

        }

 

 

        public void RecvByteData(IntPtr pData,int nLength)

        {

 

            if (nLength < 0)

            {

                throw  new ArgumentException("error_RecvByteData");

 

            }

            int nDealLength = 0;            //已经处理的数据长度

            do

            {

                pData = pData + nDealLength;

                nLength -= nDealLength;

                nDealLength = 0;

                if (nLength == 0) {

                    return;

                }

                int nHeadNeed = HeadLen - m_nRecvOffset;

                if (nHeadNeed > 0)

                {

                    if (nLength >= nHeadNeed)

                    {

                        Marshal.Copy(pData, m_bRealData, m_nRecvOffset, nHeadNeed);

                        m_nRecvOffset += nHeadNeed;

                        if (!CheckHead(m_bRealData))

                        {

                            return;

                        }

 

                        Head = (T)StructTransform.BytesToStuct(m_bRealData, typeof(T));

 

                        nDealLength += nHeadNeed;

 

                        if (m_nRecvOffset == GetPacketLength(m_bRealData))

                        {

                            OnReceivePackage(m_bRealData, m_nRecvOffset);

                            m_nRecvOffset = 0;

                        }

                        continue;

                    }

                    else

                    {

                        Marshal.Copy(m_bRealData, m_nRecvOffset, pData, nLength);

                        m_nRecvOffset += nLength;

                        return;

                    }

                }

                else

                {

                    int nPackageLength = GetPacketLength(m_bRealData);

                    if (nPackageLength < 0)

                    {

                        return;

                    }

                    if (nPackageLength > 1024)

                    {

                        byte[] pNew = new byte[nPackageLength];

                        m_bRealData.CopyTo(pNew, 0);

                       // Marshal.Copy(pNew, m_bRealData, m_nRecvOffset);

                        m_bRealData = null;

                        m_bRealData = pNew;

                        m_nAllocRealDataItem = nPackageLength;

                    }

                    int nNeed = nPackageLength - m_nRecvOffset;

                    if (nLength < nNeed)

                    {

                        Marshal.Copy(pData, m_bRealData, m_nRecvOffset, nLength);

 

                        m_nRecvOffset += nLength;

                        //数据不足,还要等下一次接收.

                        return;

                    }

                    else

                    {

                        //数据充足

                        //将需要部分全部拷入.

                        Marshal.Copy(pData, m_bRealData, m_nRecvOffset, nNeed);//全部拷入

                        //数据包,接收完整,通知数据包到达.

                        OnReceivePackage(m_bRealData, nPackageLength);

                        //接收完数据后,不删除,以便下次复用。

                        m_nRecvOffset = 0; //再重新开始。

                        nDealLength += nNeed; //添加已经处理的.

                        continue;

                    }   

                }

            }

            while (true);

 

        }

 

        /// <summary>

        /// 判断包头是否正确, 子类继承实现

        /// </summary>

        /// <param name="pRealData"></param>

        /// <returns></returns>

        public virtual bool CheckHead(byte[] pRealData)

        {

            return true;

        }

 

        /// <summary>

        /// 获取包长度,子类继承实现

        /// </summary>

        /// <param name="pRealData"></param>

        /// <returns></returns>

        public virtual int GetPacketLength(byte[] pRealData)

        {

            //测试代码

            byte[] temp = new byte[4];

            temp[0] = pRealData[12];

            temp[1] = pRealData[13];

            temp[2] = pRealData[14];

            temp[3] = pRealData[15];

 

            byte[] temp1 = new byte[4];

            temp1[0] = pRealData[0];

            temp1[1] = pRealData[1];

            temp1[2] = pRealData[2];

            temp1[3] = pRealData[3];

            return (int)BitConverter.ToInt32(temp, 0) + (int)BitConverter.ToInt32(temp1, 0);

 

        }

 

        /// <summary>

        /// 接受包完整后执行方法 

        /// </summary>

        /// <param name="ReadData"></param>

        /// <param name="len"></param>

        public virtual void OnReceivePackage(byte[] ReadData, int len)

        { 

        }

 

    }

}

原创粉丝点击