消息结构封装问题,涉及到数组与字节结构对齐.
现在由于原来的服务器平台是C++的,需要写客户端与之通信,原来平台所有网络命令都是用以下的结构来实现:
#pragma pack(1)
typedef struct _tagMessage
{
int msgType;
int lPara;
int wPara;
char lData[150];
}Message;//这个结构的大小是162个字节,每个成员按照一个字节对齐的.
#pragma pack()
服务器在发送数据的时候是:
Message mSendData;
....
send(sock,(char*)&mSendData,sizeof(mSendData),....);
如果是C++方式的接收,则每次都是:
Message mRecData;
while(1)
{
select(....)
if(条件为真)
{
recv(sock,(char*)&mRecData,szieof(mRecData),...);
//这样接收到的数据会自动按照结构的顺序去填充每一个结构成员.
}
}
问题:
在C#中的Socket类的rec方法是需要一个byte数组的.
如果结构是单纯的基本类型,则可以实现:
c#
[StructLayout(LayoutKind.Sequential,Size=12)] public struct Message
{
int msgType;
int lPara;
int wPara;
}
byte []data=new byte[12];
msocke.recv(data,...)//接收12个字节到data数组中,
//下面的代码将数组COPY到结构中:
Message m_Msg=new Message();
CHandle m_byteHandle,m_msgStrHandle;
m_msgStrHandle = GCHandle.Alloc(m_Msg, GCHandleType.Pinned);
Marshal.Copy(data,0,m_msgStrHandle.AddrOfPinnedObject(),Marshal.SizeOf(m_Msg));
//就是先取得结构的地址,之后将data数组的数值COPY到该地址中去,即是COPY到m_Msg中去.
这样字段也会自动填充到C#的结构对应的字段中去,但是这个前提是在C++的结构是没有char lData[150];成员的!
如果存在这个成员,在C#中怎么处理?
C#根本没有byte data[150]这样的数组的!难道要定义150/4个int 是数据吗?
我想到的方法是:
data里面的数据是没有格式的了,只是数据来的,可以在发送端定义有char data[150]的成员,在接收段定义的却没有这个成员的结构,接收时使用162大小的数组进行接收,之后在COPY到数组的时候只COPY前面三个成员的字节大小,后面的数据在COPY到另外一个byte数组中.
还有就是C#的:
byte[]data1=new byte[100];
byte []data2=new byte[100];
怎么把data1的数据COPY到data2去,除了我上面使用地址的方法之外.