C#用socket传输类或结构,以及结构和bytes[]互转
来源:互联网 发布:网络彩票与实体店结合 编辑:程序博客网 时间:2024/06/10 03:14
最近有一项目,是和另外一家公司合作,需要接收对方发来的结构消息,然后填充好后发回。
涉及到利用socket传输和接收struct。
一般情况下我们只需要利用C#提供的序列化和反序列化即可,将class/struct声明为可序列化的。
然后利用BinaryFormatter之类的方法进行序列化及反序列化操作~自己可以Google一下:C#序列化
但是假如对方平台为C++或其它非.NET平台,这样做就不行了。由于不同平台类型之间的差异,
所以有不小的麻烦。
先附上C++与C#之间的类型对应关系:
需要注意的是非托管的BOOL在C#中对应System.Int32。而在API调用时直接用bool即可。
socket传输的是byte[].所以我们需要把struct转化为byte[]. 有高人为我们提供了如下方法。
//struct转换为byte[]static byte[] StructToBytes(object structObj) { int size = Marshal.SizeOf(structObj); IntPtr buffer = Marshal.AllocHGlobal(size); try { Marshal.StructureToPtr(structObj, buffer, false); byte[] bytes = new byte[size]; Marshal.Copy(buffer, bytes, 0, size); return bytes; } finally { Marshal.FreeHGlobal(buffer); } } //byte[]转换为structstatic object BytesToStruct(byte[] bytes, Type strcutType) { int size = Marshal.SizeOf(strcutType); IntPtr buffer = Marshal.AllocHGlobal(size); try { Marshal.Copy(bytes, 0, buffer, size); return Marshal.PtrToStructure(buffer, strcutType); } finally { Marshal.FreeHGlobal(buffer); } }
一般情况下到此就结束了。但是假如struct里面除了基本数据类型int,long,byte之外,还有 char*.比如:
typedef struct{ char szStatus[924]; char szError[196]; BYTE bEmergent;} CHECK_STATUS_PARAM
为了确保数据传输和读取的正确性,应该固定字符串的长度。
此处就涉及到了:字符串的封送处理。见:http://msdn.microsoft.com/zh-cn/library/s9ts558h(VS.80).aspx
在不同的情况下我们需要采用不同的封送选项。
结构中使用的字符串
字符串是结构的有效成员;但是,StringBuilder 缓冲区在结构中是无效的。下表显示当字符串数据类型被作为字段封送时该类型的封送处理选项。MarshalAsAttribute 属性提供了若干个 UnmanagedType 枚举值,以便将字符串封送到字段。
枚举类型 非托管格式的说明
UnmanagedType.BStr
具有预设长度和 Unicode 字符的 COM 样式的 BSTR。
UnmanagedType.LPStr
指向 ANSI 字符的空终止数组的指针。
UnmanagedType.LPTStr
指向平台相关的字符的空终止数组的指针。
UnmanagedType.LPWStr
指向 Unicode 字符的空终止数组的指针。
UnmanagedType.ByValTStr
定长的字符数组;数组的类型由包含数组的结构的字符集确定。
项目要求采用ANSI编码,于是C#对应的stuctr为:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]public struct CHECK_STATUS_PARAM{[MarshalAs( UnmanagedType.ByValTStr, SizeConst = 924 )]public string szStatus;[MarshalAs( UnmanagedType.ByValTStr, SizeConst = 196 )]public string szError;public byte bEmergent;}
- C#用socket传输类或结构,以及结构和bytes[]互转
- Linux socket 传输和接受结构体
- c#中利用结构体进行socket传输数据
- 谈Socket传输结构体
- C++ socket传输结构体
- C#和C++结构体Socket通信
- C#和C++结构体Socket通信
- C#和C++结构体Socket通信
- C#和C++结构体Socket通信
- C#和C++结构体Socket通信
- C#和C++结构体Socket通信
- C#和C++结构体Socket通信
- C#和C++结构体Socket通信
- C#结构和类
- C#类和结构
- C# 类和结构
- 【转】socket不能直接传输结构体!
- socket传输结构体send()
- C++的list的函数
- Extjs实现多个Grid使用同一个Store,但显示不同的内容
- 使用sp_getapplock限制用户顺序访问存储过程
- 结构——复合值类型
- 函数声明和定义
- C#用socket传输类或结构,以及结构和bytes[]互转
- UNIX系统编程1《笔记》
- 在linux应用程序使用system函数执行简单的shell交互命令的方法
- plsql 语法、过程、函数、包、触发器
- 面试了---
- 一周以来的工作总结--oracle分区的迁移
- 书籍 相关收集
- 2012年10月17日工作总结
- 枚举——复合值类型