当前位置:文档之家› c++与c#的结构socket体通讯

c++与c#的结构socket体通讯

C#和C++结构体Socket通信

最近在用C#做一个项目的时候,Socket发送消息的时候遇到了服务端需要接收C++结构体的二进制数据流,这个时候就需要用C#仿照C++的结构体做出一个结构来,然后将其转换成二进制流进行发送,之后将响应消息的二进制数据流转换成C#结构。

1、仿照C++结构体写出C#的结构来

1using System.Runtime.InteropServices;

2

3 [Serializable] // 指示可序列化

4 [StructLayout(LayoutKind.Sequential, Pack =1)] // 按1字节对齐

5public struct Operator

6

7 {

8public ushort id;

9 [MarshalAs(UnmanagedType.ByValArray, SizeConst =11)] // 声明一个字符数组,大小为11

10public char[] name;

11 [MarshalAs(UnmanagedType.ByValArray, SizeConst =9)]

12public char[] pass;

13

14public Operator(string user, string pass) // 初始化

15 {

16this.id = 10000;

https://www.doczj.com/doc/8213437867.html, = user.PadRight(11, '\0').ToCharArray();

18this.pass = pass.PadRight(9, '\0').ToCharArray();

19 }

20 }

21

22

2、注意C#与C++数据类型的对应关系

1typedef

2{

3 WORD id;

4 CHAR name[

5 CHAR password[

6}Operator;

7

8

1

2

3

4

5

6

7

8

9 {

10

11

12

13

14

15 IntPtr structPtr =

16

17 Marshal.StructureToPtr(obj, structPtr, 18

19 Marshal.Copy(structPtr, bytes, 0, size);

20//释放内存空间

21 Marshal.FreeHGlobal(structPtr);

22//返回byte数组

23return bytes;

24

25 }

26

27

接收的时候需要把字节数组转换成结构

1///

2/// byte数组转结构

3///

4///byte数组

5///结构类型

6///转换后的结构

7public object BytesToStruct(byte[] bytes, Type type)

8 {

9//得到结构的大小

10int size = Marshal.SizeOf(type);

11 Log(size.ToString(), 1);

12//byte数组长度小于结构的大小

13if (size > bytes.Length)

14 {

15//返回空

16return null;

17 }

18//分配结构大小的内存空间

19 IntPtr structPtr = Marshal.AllocHGlobal(size);

20//将byte数组拷到分配好的内存空间

21 Marshal.Copy(bytes, 0, structPtr, size);

22//将内存空间转换为目标结构

23object obj = Marshal.PtrToStructure(structPtr, type);

24//释放内存空间

25 Marshal.FreeHGlobal(structPtr);

26//返回结构

27return obj;

28 }

29

4、实际操作:

1using System.Collections;

2using System.Collections.Generic;

3using https://www.doczj.com/doc/8213437867.html,;

4using https://www.doczj.com/doc/8213437867.html,.Sockets;

5

6byte[] Message = StructToBytes(new Operator("user","pass")); // 将结构转换成字节数组

7

8TcpClient socket =new TcpClient();

9

10socket.Connect(ip,port);

11

12NetworkStream ns = Socket.GetStream();

13

14ns.Write(Message,0,Message.Length); // 发送

15

16byte[] Recv =new byte[1024]; // 缓冲

17

18int NumberOfRecv =0;

19

20IList newRecv =new List();

21ns.ReadTimeout =3000;

22try

23{

24do

25{

26// 接收响应

27NumberOfRecv = ns.Read(Recv, 0, Recv.Length);

28for (int i =0; i < NumberOfRecv; i++)

29newRecv.Add(Recv[i]);

30}

31while (ns.DataAvailable);

32byte[] resultRecv =new byte[newRecv.Count];

33newRecv.CopyTo(resultRecv, 0);

34

35Operator MyOper =new Operator();

36

37MyOper = (Operator)BytesToStruct(resultRecv, MyOper.GetType()); // 将字节数组转换成结构

38

在这里取值的时候可能会出现只能取到一个字段,剩余的取不到的问题,怎么回事我也搞不懂,反正我的解决办法就是按照字节的顺序从resultRecv里分别取出对应的字段的字节数组,然后解码,例如:

https://www.doczj.com/doc/8213437867.html,是11个字节,最后一位是0,Operator.id是2个字节,那么从第3位到第12位的字节就是https://www.doczj.com/doc/8213437867.html,的内容,取出另存为一个数组MyOperName,Encoding.Default.GetString(MyOperName)就是

https://www.doczj.com/doc/8213437867.html,的内容。

1socket.Close();

2

3ns.Close();

4

相关主题
文本预览
相关文档 最新文档