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)
{
}
}
}