Как преобразовать структуру в байтовый массив в C #? - PullRequest
71 голосов
/ 19 июля 2010

Как мне преобразовать структуру в байтовый массив в C #?

Я определил такую ​​структуру:

public struct CIFSPacket
{
    public uint protocolIdentifier; //The value must be "0xFF+'SMB'".
    public byte command;

    public byte errorClass;
    public byte reserved;
    public ushort error;

    public byte flags;

    //Here there are 14 bytes of data which is used differently among different dialects.
    //I do want the flags2. However, so I'll try parsing them.
    public ushort flags2;

    public ushort treeId;
    public ushort processId;
    public ushort userId;
    public ushort multiplexId;

    //Trans request
    public byte wordCount;//Count of parameter words defining the data portion of the packet.
    //From here it might be undefined...

    public int parametersStartIndex;

    public ushort byteCount; //Buffer length
    public int bufferStartIndex;

    public string Buffer;
}

В моем методе main я создаю его экземпляр и присваиваю ему значения:

CIFSPacket packet = new CIFSPacket();
packet.protocolIdentifier = 0xff;
packet.command = (byte)CommandTypes.SMB_COM_NEGOTIATE;
packet.errorClass = 0xff;
packet.error = 0;
packet.flags = 0x00;
packet.flags2 = 0x0001;
packet.multiplexId = 22;
packet.wordCount = 0;
packet.byteCount = 119;

packet.Buffer = "NT LM 0.12";

Теперь я хочу отправить этот пакет по сокету. Для этого мне нужно преобразовать структуру в байтовый массив. Как я могу это сделать?

Мой полный код выглядит следующим образом.

static void Main(string[] args)
{

  Socket MyPing = new Socket(AddressFamily.InterNetwork,
  SocketType.Stream , ProtocolType.Unspecified ) ;


  MyPing.Connect("172.24.18.240", 139);

    //Fake an IP Address so I can send with SendTo
    IPAddress IP = new IPAddress(new byte[] { 172,24,18,240 });
    IPEndPoint IPEP = new IPEndPoint(IP, 139);

    //Local IP for Receiving
    IPEndPoint Local = new IPEndPoint(IPAddress.Any, 0);
    EndPoint EP = (EndPoint)Local;

    CIFSPacket packet = new CIFSPacket();
    packet.protocolIdentifier = 0xff;
    packet.command = (byte)CommandTypes.SMB_COM_NEGOTIATE;
    packet.errorClass = 0xff;
    packet.error = 0;
    packet.flags = 0x00;
    packet.flags2 = 0x0001;
    packet.multiplexId = 22;
    packet.wordCount = 0;
    packet.byteCount = 119;

    packet.Buffer = "NT LM 0.12";

    MyPing.SendTo(It takes byte array as parameter);
}

Каким будет фрагмент кода?

Ответы [ 13 ]

0 голосов
/ 11 июня 2014

@ Абдель Олакара, ответ, который не работает в .net 3.5, должен быть изменен следующим образом:

    public static void ByteArrayToStructure<T>(byte[] bytearray, ref T obj)
    {
        int len = Marshal.SizeOf(obj);
        IntPtr i = Marshal.AllocHGlobal(len);
        Marshal.Copy(bytearray, 0, i, len);
        obj = (T)Marshal.PtrToStructure(i, typeof(T));
        Marshal.FreeHGlobal(i);
    }
0 голосов
/ 19 июля 2010

Выглядит как предопределенная (уровень C) структура для некоторой внешней библиотеки.Маршал твой друг.Проверьте:

http://geekswithblogs.net/taylorrich/archive/2006/08/21/88665.aspx

для начала, как с этим справиться.Обратите внимание, что вы можете - с атрибутами - определять такие вещи, как разметка байтов и обработка строк.ОЧЕНЬ хороший подход, на самом деле.

Ни BinaryFormatter, ни MemoryStream не подходят для этого.

0 голосов
/ 19 июля 2010

Я бы взглянул на классы BinaryReader и BinaryWriter.Недавно мне пришлось сериализовать данные в байтовый массив (и обратно), и я нашел эти классы только после того, как сам переписал их.страница тоже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...