基于异步socket客户端接收数据基础类。
2011-01-17 11:05
549 查看
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)
{
}
}
}
{
/// <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)
{
}
}
}
相关文章推荐
- 异步Socket接收数据后缓存处理问题
- 黑马程序员--Java基础学习之网络编程(TCP、UDP、Socket、模拟发送和接收数据)
- WSAAsyncSelect模型 实现socket客户端接收数据的例子
- 关于异步socket接收数据的困惑
- Python入门:socket连续接收客户端数据
- WSAAsyncSelect模型 实现socket客户端接收数据的例子
- ext异步请求一个aspx/ashx/web service取得数据,服务端返回一个json.然后客户端接收并显示.
- C#网络Socket的数据发送与接收处理(利用异步)的模板(模式)
- 2,socket循环接收数据:socket循环接收大数据,问:socket异步接收数据?
- Socket编程如何实现服务器端接收客户端数据
- 基于UDP协议的网络编程(使用DatagramSocket发送接收数据)
- 异步 SOCKET 编程 - 发送和接收数据
- C++socket客户端select异步连接发送接收数据
- socket服务器发送大数据,客户端循环接收
- 异步 SOCKET 编程 - 发送和接收数据
- Java Socket 服务端发送数据 客户端接收数据
- 异步 SOCKET 编程 - 发送和接收数据
- 异步SOCKET编程-发送和接收数据[转]
- 关于socket客户端接收不定长数据的解决方案
- socket客户端数据发送的数据服务端接收不到