Structs auf Byte-Arrays Buchsen senden über
-
19-08-2019 - |
Frage
Was ist der beste Weg, um einen Byte-Array von einer Struktur senden über TCP-Sockets zu bekommen? Ich verwende .NET (VB oder C #).
Lösung
Wenn Sie C # verwenden, können Sie es auch zu einem nativen Marschall selbst Puffer, eine bessere Kontrolle über die Serialisierung zu haben.
Sie müßten das entsprechende Attribut auf Ihre Struktur hinzuzufügen,
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack=1)]
Dann können Sie serialisiert es mit:
/// <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;
}
Andere Tipps
Sie sollten schauen Sie in Serialisierung . Es gibt eine Reihe von Optionen zur Verfügung, von Protocol Puffer (Implementierungen von der 1. und 2. SO Benutzer gewählt) auf Xml auf die BinaryFormatter .
Wenn Sie bereit sind, kümmern sich um die Endian sind (in einem heterogenen Netzwerk zu kommunizieren), der einzige Weg, dies zu tun ist, Feld für Feld.
Warum nicht nur einen binären Leser verwenden, um Felder der Struktur zu füllen, und wieder lesen sie aus? Alles, was Sie wissen müssen, ist die Größe der Felder in der Struktur und seine Position in dem Strom, keine Notwendigkeit für nicht verwaltete Lösungen .. Hier ist ein Beispiel von einem Waveplayer Ich schrieb ..
/// <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;
}
Sie müssen spezifischere und sagen Sie uns Ihre Sprache.
Für viele Sprachen gibt es vorgefertigte Gerüste oder sogar Teile der Standardumgebung Sprache, für diese Art von Dingen zu tun.
Ich gehe davon aus, die Sprache C, da Sie sagen, „Struktur“
Sie können eine Funktion namens verwenden
ssize_t write (int fd, const void * buf, size_t count);
wobei FD der FileDescriptor der Buchse ist der Puffer ist die Adresse der Struktur, und die Zählung ist die Größe in Bytes
Sie würden verwenden Sie es als:
write (Buchse, & struct_var, sizeof (struct_var));