Pergunta

Qual é a melhor maneira de obter um array de bytes de um struct para enviar mais sockets TCP? Estou usando .Net (VB ou C #).

Foi útil?

Solução

Se você estiver usando C #, você também pode empacotá-lo para um buffer nativo si mesmo, para ter melhor controle sobre a serialização.

Você precisa adicionar o atributo apropriado para o seu struct,

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

Em seguida, você pode serializar-lo usando:

    /// <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;
    }

Outras dicas

Você deve olhar para serialização . Há um número de opções disponíveis para você, a partir Protocolo Tampões (implementações de 1º e 2º classificados tão usuários) para Xml para o BinaryFormatter .

Se você estiver disposto a cuidar do endian (para se comunicar em uma rede heterogênea), a única maneira de fazer isso é campo a campo.

Porque não basta usar um leitor de binário para preencher os campos da struct, e lê-los novamente? Tudo que você precisa saber é o tamanho dos campos na struct e da posição no fluxo, não há necessidade de soluções não gerenciados .. Aqui está um exemplo de um waveplayer eu escrevi ..

    /// <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;
    }

Você precisa ser mais específico e diga-nos o seu idioma.

Para muitas línguas, existem estruturas prontas, ou mesmo partes do ambiente padrão da linguagem, para fazer esses tipos de coisas.

Estou assumindo a linguagem C, uma vez que você diz "struct"

Você pode usar uma função chamada

gravar ssize_t (int fd, const void * buf, size_t contagem);

onde FD é o FileDescriptor do soquete o tampão é o endereço da estrutura, e a contagem é o tamanho em bytes

você iria usá-lo como:

write (soquete, & struct_var, sizeof (struct_var));

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top