Структуры в байтовые массивы для отправки через сокеты

StackOverflow https://stackoverflow.com/questions/650815

Вопрос

Каков наилучший способ получить массив байтов из структуры для отправки через сокеты TCP? Я использую .Net (VB или C #).

Это было полезно?

Решение

Если вы используете C #, вы также можете самостоятельно упаковать его в собственный буфер, чтобы лучше контролировать сериализацию.

Вам необходимо добавить соответствующий атрибут в вашу структуру,

  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack=1)]

Затем вы можете сериализовать его, используя:

    /// <summary>
    /// Serializes the specified object into a byte array.
    /// </summary>
    /// <param name="nativeObject">The object to serialize.</param>
    /// <returns></returns>
    public static byte[] Serialize(object obj)
    {
        Type objectType = obj.GetType();
        int objectSize = Marshal.SizeOf(obj);
        IntPtr buffer = Marshal.AllocHGlobal(objectSize);
        Marshal.StructureToPtr(obj, buffer, false);
        byte[] array = new byte[objectSize];
        Marshal.Copy(buffer, array , 0, objectSize);
        Marshal.FreeHGlobal(buffer);
        return array;
    }

Другие советы

Вам следует изучить сериализацию . Вам доступно несколько вариантов: Протокол Буферы (реализации пользователями SO первого и второго ранга) для XML для BinaryFormatter .

Если вы хотите позаботиться о порядке байтов (для связи в гетерогенной сети), единственный способ сделать это - поле за полем.

Почему бы просто не использовать двоичный ридер для заполнения полей структуры и снова их считывать? Все, что вам нужно знать, это размер полей в структуре и их положение в потоке, нет необходимости в неуправляемых решениях. Вот пример из waveplayer, который я написал ..

    /// <summary>Copies header to a stream</summary>
    /// <param name="waveData">Wav data stream</param>
    /// <param name="format">WAVEFORMATEX wav format</param>
    /// <returns>Stream</returns>
    public Stream CreateStream(Stream waveData, WAVEFORMATEX format)
    {
        MemoryStream stream = new MemoryStream();
        BinaryWriter writer = new BinaryWriter(stream);

        writer.Write(System.Text.Encoding.ASCII.GetBytes("RIFF".ToCharArray()));
        writer.Write((Int32)(waveData.Length + 36)); //File length minus first 8 bytes of RIFF description
        writer.Write(System.Text.Encoding.ASCII.GetBytes("WAVEfmt ".ToCharArray()));
        writer.Write((Int32)16); //length of following chunk: 16
        writer.Write((Int16)format.wFormatTag);
        writer.Write((Int16)format.nChannels);
        writer.Write((Int32)format.nSamplesPerSec);
        writer.Write((Int32)format.nAvgBytesPerSec);
        writer.Write((Int16)format.nBlockAlign);
        writer.Write((Int16)format.wBitsPerSample);
        writer.Write(System.Text.Encoding.ASCII.GetBytes("data".ToCharArray()));
        writer.Write((Int32)waveData.Length);

        waveData.Seek(0, SeekOrigin.Begin);
        byte[] b = new byte[waveData.Length];
        waveData.Read(b, 0, (int)waveData.Length);
        writer.Write(b);
        writer.Seek(0, SeekOrigin.Begin);
        return stream;
    }

Вам нужно быть более конкретным и сообщить нам свой язык.

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

Я предполагаю, что язык C, так как вы говорите " struct "

вы можете использовать функцию под названием

  

ssize_t write (int fd, const void * buf,   size_t count);

где FD - файловый дескриптор сокета буфер - это адрес структуры, а count - это размер в байтах

вы бы использовали его как

  

write (сокет, & amp; struct_var, sizeof (struct_var));

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top