Was ist der beste Weg, um ein Byte-Array von einer Struktur über TCP-Sockets senden zu bekommen? Ich benutze .Net (VB oder C#).Structes zu Byte-Arrays zum Senden über Sockets
Antwort
Wenn Sie C# verwenden, können Sie es auch selbst in einen nativen Puffer marshallen, um die Serialisierung besser steuern zu können.
Sie müssten das entsprechende Attribut auf Ihre Struktur hinzuzufügen,
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack=1)]
Dann können Sie es mit Serialisierung:
/// <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;
}
Sie müssen genauer und sagen Sie uns Ihre Sprache.
Für viele Sprachen gibt es vorgefertigte Frameworks oder sogar Teile der Standardumgebung der Sprache, um solche Dinge zu tun.
Wenn Sie bereit sind, sich um den Endian zu kümmern (um in einem heterogenen Netzwerk zu kommunizieren), ist der einzige Weg, dies zu tun, Feld für Feld.
ich die C-Sprache gehe davon aus, da sagen Sie "Struktur"
Sie eine Funktion
ssize_t write (int fd, const void * buf, size_t count) genannt verwenden können;
wobei FD die FileDescriptor der Buchse ist der Puffer die Adresse der Struktur ist, und die Zählung ist die Größe in Bytes
Sie es als nutzen würde:
write (Buchse, & struct_var, sizeof (struct_var));
Setzt das Konto für Ausrichtung, Verpackung und Endianess? – sharptooth
nein, tut es nicht. Für endianness müssten Sie eine Funktion wie htonl, htons, ntohl, ntohs verwenden, die Werte zwischen Host- und Netzwerk-Byte-Reihenfolge konvertieren. Zum Packen können Sie Ihren Compiler verwenden, um eine bestimmte Packstruktur oder Ausrichtung zu erzwingen. –
Sie sollten in Serialization suchen. Es stehen Ihnen verschiedene Optionen zur Verfügung, von ProtocolBuffers (Implementierungen durch die ersten und zweiten Platzierten SO-Benutzer) bis Xml bis BinaryFormatter.
Warum ein binäres Leser nicht nur zum Auffüllen verwenden Felder der Struktur , und lies sie wieder aus? Alles, was Sie wissen müssen, ist die Größe der Felder in der Struktur und seine Position in dem Strom, schrieb ich ..
/// <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;
}
Was Ihre Umgebung keine Notwendigkeit für nicht verwaltete Lösungen .. Hier ein Beispiel aus einem Waveplayer ist, ist (.NET, Java, C/C++)? Nichts geht ohne diese Info. –
Welche Programmiersprache benutzen Sie? – Groo