运维开发网

如何从socket接收字节数组,到C#结构

运维开发网 https://www.qedev.com 2020-07-05 08:34 出处:网络 作者:运维开发网整理
我必须开发一个服务(C#),它通过TCP Socket从网络设备读取数据并转换它是C#结构. 我基于现有的旧Delphi应用程序,它正在做所有这些事情,我必须在C#中迁移逻辑. 编辑: 我从原始数据结构的C-Source获得了一个快照: struct _RequestMsgStruct { UCHAR request_ver; //In DELPHI it is rep
我必须开发一个服务(C#),它通过TCP Socket从网络设备读取数据并转换它是C#结构.

我基于现有的旧Delphi应用程序,它正在做所有这些事情,我必须在C#中迁移逻辑.

编辑:

我从原始数据结构的C-Source获得了一个快照:

struct _RequestMsgStruct
{
    UCHAR           request_ver; //In DELPHI it is represented as Byte
    USHORT          mac_addr[3];    /* MAC Address */
    UINT            product_type; //In DELPHI - Cardinal
    UCHAR           supply_type; //In DELPHI - Byte
    short           reserved0; //In DELPHI - SmallInt
    UCHAR           oper_ver[4]; //In DELPHI - CARDINAL !!!
    USHORT          brd_id; //In DELPHI - WORD
    unsigned short  exp_id1; //In DELPHI - WORD

    //In DELPHI - string[15]; //Array [0..15] of char;
    UCHAR           serial_no[16]; /* Serial Number. 16th char have to be NULL */ 
    UCHAR           _name[32]; /* Name */ //Length of payload may vary //In DELPHI - string[31]

    float           data_avg; //In DELPHI - Single
    ULONG           key[5]; //In DELPHI - array [0..19] of Byte
}__attribute__ ((packed));

Delphi Packed记录包含200多个不同类型的字段……看起来大致如下:

TREC_DATA = packed record
      ID            : Byte;
      MAC_ADDRESS   : array [0..5] of Byte;
      fieldCard     : cardinal;
      fieldSI       : SmallInt; 
      fieldW        : WORD;
      SERIAL_NUMBER : string[15]; //Array [0..15] of char;
      fieldSingle   : Single;
      fieldArrOfB   : array [0..19] of Byte;
    end;

要在Delphi中将字节数组移动到结构,有下一个代码:

Move(inBytesArr[StartIdx], DelphiStruct, aMsgSize)

要转换字符串文件(例如SERIAL_NUMBER),还有这样的代码:

var
  pc: Pchar;
...
pc := @inBytesArr[StartIdx + SerialN_Pos_Idx];
DelphiStruct.SERIAL_NUMBER := pc;

我第一次处理这种转换,我不知道从哪里开始:

>如何将此结构转换为c#?

– 我应该使用LayoutKind.Sequential或LayoutKind.Explicit,还是wiyhout [FieldOffset(N)]属性?

– 我如何在目标c#结构中声明字节数组:作为固定缓冲区或使用[MarshalAs(UnmanagedType.ByValArray …)]属性?

>哪种方法可以将输入字节数组编组到最终的C#结构:使用Marshal.PtrToStructure或GCHandle.Alloc(bytes,GCHandleType.Pinned)AddrOfPinnedObject?

请帮助我,至少,从我需要开始的地方获得低估的起点.

默认情况下,Delphi的打包记录按单字节边界对齐字段.

因此,你应该使用这样的东西:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TREC_DATA
{
      public byte ID;
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
      public byte[] MAC_ADDRESS;
      public uint fieldCard;
      public short fieldSI;
      public ushort fieldW;
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
      public byte[] SERIAL_NUMBER;
      public float fieldSingle;
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
      public byte[] fieldArrOfB;    
}

我唯一不确定(现在没有Deplhi就无法测试)的是SERIAL_NUMBER字段.

更新后:原来,SERIAL_NUMBER只是一个以空字符结尾的字符串.

0

精彩评论

暂无评论...
验证码 换一张
取 消