基於異步socket客戶端接收數據基礎類。

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)

        { 

        }

 

    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章