服务器和客户端之间数据传输的协议,如果我们可以使用对象(结构)来封装,
会给程序设计上带来极大的便利。
HP-SOCKET为我们提供了PACK模式,让我们不用去考虑沾包,掉包的问题;
我们还可以再便利一些,把数据对象直接传递,放弃简陋的字符串报文。
下面用HP-SOCKET实现了一个 服务器和客户端的实例。底层报文是二进制byte转对象的数据。
我们在客户端定义一个数据对象:
[StructLayout(LayoutKind.Sequential)]
public struct objecttext
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
public string logontime;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
public string Rtxt;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
public string Stxt;
}
产生数据对象实例并赋值:
objecttext ot = new objecttext { Stxt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") };
在客服端把对象转成byte:
byte[] bytes = StructureToByte<objecttext>(ot);
在客服端让HP-SOCKET把这堆bytes传出去:
client.Send(bytes, bytes.Length)
在服务器端的事件响应函数中收到bytes数据并还原成对象:
HandleResult OnReceive(TcpServer sender , IntPtr connId, byte[] bytes )
{
objecttext ot = ByteToStructure<objecttext>(bytes);
return HandleResult.Ok;
}
配套例子程序的使用:
1、服务器程序运行。
2、客户端程序连接。
3、客户端程序每秒发一个数据包给服务器,这个数据包是一个结构(对象),里面包含三个字段,但被转换为二进制byte格式。

4、服务器接收数据包byte,把二进制socket报文还原为结构(对象),然后定时处理这个消息队列。
这里是重点查了很多资料,服务器和客户端程序不同,没有用同一个DLL,也没有改变命名空间。直接对报文结构还原,2018年春节晚上都在玩这个,终于解决了,原来在定义结构对象时候,字段必须指定为定长,像这样定义:
[StructLayout(LayoutKind.Sequential)]
public struct objecttext
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
public string logontime;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
public string Rtxt;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
public string Stxt;
}
全部配套源码:
本文介绍如何使用HP-SOCKET的PACK模式简化服务器与客户端之间的数据传输,通过实例演示了如何封装数据对象进行二进制传输,避免沾包、掉包问题,实现了更高效的数据交换。
4060

被折叠的 条评论
为什么被折叠?



