Question

Quel est le meilleur moyen d’obtenir un tableau d’octets d’une structure pour l’envoyer sur des sockets TCP? J'utilise .Net (VB ou C #).

Était-ce utile?

La solution

Si vous utilisez C #, vous pouvez également le structurer vous-même dans un tampon natif afin de mieux contrôler la sérialisation.

Vous devez ajouter l'attribut approprié à votre structure,

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

Vous pouvez ensuite le sérialiser en utilisant:

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

Autres conseils

Vous devriez examiner la Sérialisation . Plusieurs options s'offrent à vous, à partir du Protocole Tampons (implémentations par les utilisateurs SO les 1re et 2e rangs) à XML vers BinaryFormatter .

Si vous êtes prêt à prendre soin de l’endian (pour communiquer dans un réseau hétérogène), la seule façon de le faire est d’utiliser champ par champ.

Pourquoi ne pas utiliser simplement un lecteur binaire pour renseigner les champs de la structure et les relire? Tout ce que vous devez savoir, c'est la taille des champs dans la structure et sa position dans le flux, pas besoin de solutions non gérées. Voici un exemple d'un waveplayer que j'ai écrit.

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

Vous devez être plus précis et nous dire votre langue.

Pour de nombreuses langues, il existe des frameworks prêts à l'emploi, voire des parties de l'environnement standard du langage, qui permettent ce genre de choses.

J'assume le langage C puisque vous dites "struct"

vous pouvez utiliser une fonction appelée

  

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

où FD est le descripteur de fichier de socket le tampon est l'adresse de la structure et count la taille en octets

vous l'utiliseriez comme:

  

write (socket, & amp; struct_var, sizeof (struct_var));

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top