有个项目,通过SOCKET通信方式向服务器发送消息。消息由消息头和消息体组成,消息头采用结构体格式,格式如下:
4字节序
1 编号(4byte)
2 协议版本(1byte) 保留(1byte) 保留(1byte) 保留(1byte)
3 保留(4byte)
4 数据类型(4byte)
5 数据体部分(XML格式消息体) 编号(4byte):固定为0x11FFFF11
协议版本(1byte):0x12
数据类型(4byte):0x3FFF0011 数据体部分(XML格式消息体)
<xml>
<data>............</data>
</xml>这个结构体用C#应该如何写,望大家能指教下,谢谢。
4字节序
1 编号(4byte)
2 协议版本(1byte) 保留(1byte) 保留(1byte) 保留(1byte)
3 保留(4byte)
4 数据类型(4byte)
5 数据体部分(XML格式消息体) 编号(4byte):固定为0x11FFFF11
协议版本(1byte):0x12
数据类型(4byte):0x3FFF0011 数据体部分(XML格式消息体)
<xml>
<data>............</data>
</xml>这个结构体用C#应该如何写,望大家能指教下,谢谢。
以前我写的 /// <summary>
/// 定义Tcp消息类
/// </summary>
[Serializable()]
public sealed class TcpMsg
{
#region -变量定义 /// <summary>
/// 消息类别
/// </summary>
private LogType m_strMsgType = LogType.NO; /// <summary>
/// 定义消息状态
/// </summary>
private TcpMsgState m_strMsgState = TcpMsgState.None; /// <summary>
/// 定义数据键值
/// </summary>
private string m_strMsgKey = null; /// <summary>
/// 消息
/// </summary>
private string m_strMsg = null; #endregion #region -构造 /// <summary>
/// 构造函数
/// </summary>
public TcpMsg()
{ } /// <summary>
/// 构造函数
/// </summary>
/// <param name="ltType">消息类型</param>
public TcpMsg(LogType ltType)
{
this.m_strMsgType = ltType;
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="ltType">消息类型</param>
/// <param name="State">操作状态</param>
public TcpMsg(LogType ltType, TcpMsgState State)
: this(ltType)
{
this.m_strMsgState = State;
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="ltType">消息类型</param>
/// <param name="State">操作状态</param>
/// <param name="Msg">消息</param>
public TcpMsg(LogType ltType, TcpMsgState State, string strMsg)
: this(ltType, State)
{
this.m_strMsg = strMsg;
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="ltType">消息类型</param>
/// <param name="State">操作状态</param>
/// <param name="Msg">消息</param>
/// <param name="strKey">操作主键</param>
public TcpMsg(LogType ltType, TcpMsgState State, string strMsg, string strKey)
: this(ltType, State, strMsg)
{
this.m_strMsgKey = strKey;
} #endregion #region -属性方法 /// <summary>
/// 取得或者设置消息头标志
/// </summary>
public TcpMsgState State
{
get
{
return this.m_strMsgState;
}
set
{
this.m_strMsgState = value;
}
} /// <summary>
/// 取得或者设置消息类别
/// </summary>
public LogType Type
{
get
{
return this.m_strMsgType;
}
set
{
this.m_strMsgType = value;
}
} /// <summary>
/// 取得或者设置数据键值
/// </summary>
public string Key
{
get
{
return this.m_strMsgKey;
}
set
{
this.m_strMsgKey = value;
}
} /// <summary>
/// 取得或者设置消息
/// </summary>
public string Msg
{
get
{
return this.m_strMsg;
}
set
{
this.m_strMsg = value;
}
} #endregion
}
可以使用类似生成者消费者的模式
做一个数据缓冲池,把SOCKET接收的数据流按顺序放入缓冲区(生产者),启动一个解析线程从数据缓冲池中提取数据,按你的消息格式解析(消费者)
缓冲区可以用Queue<T>
注意线程同步
byte[] context=new byte[数据长度];//数据内容,这里是你的XML格式消息体,主要是序列化后的存储
byte[] contextlength=new byte[context.Length];//数据长度内容,内容为context长度序列化后的存储
然后将上述三个信息的内容按顺序拷贝到以下数组中
byte[] Msg=new byte[begin.Length+contextlength.Length+context.Length];
Msg就是你最后要发送的信息,这大致是个例子,和你上面的信息格式有些出入,可以参照下看看
[StructLayout(LayoutKind.Sequential)]
struct TcpMsg
{
public TcpMsg(string 数据体部分1)
{
this.编号 = 0x11FFFF11;
this.协议版本 = 0x12;
this.数据类型 = 0x3FFF0011;
this.数据体部分 = 数据体部分1; this.保留1 = 0;
this.保留2 = 0;
this.保留3 = 0;
this.保留4 = 0;
} public int 编号;
public byte 协议版本;
public byte 保留1;
public byte 保留2;
public byte 保留3;
public int 保留4;
public int 数据类型;
public string 数据体部分;
}