Ich möchte meine Struktur über ein TcpStream
senden. Ich könnte String
oder u8
senden, aber ich kann keine beliebige Struktur senden. Zum Beispiel:
Nach Erhalt der Daten möchte ich &[u8]
zurück in MyStruct
konvertieren. Wie kann ich zwischen diesen beiden Darstellungen konvertieren?
Ich weiß, dass Rust über ein JSON-Modul zum Serialisieren von Daten verfügt, aber ich möchte JSON nicht verwenden, weil ich Daten so schnell und so klein wie möglich senden möchte, damit ich keinen oder sehr geringen Overhead haben möchte.
(Schamlos aus Renato Zannons Kommentar zu einer ähnlichen Frage gestohlen )
Vielleicht würde eine Lösung wie bincode
zu Ihrem Fall passen? Hier ist ein Arbeitsbeispiel:
Cargo.toml
%Vor%main.rs
%Vor%Sie könnten dann die Bytes senden, wo immer Sie wollen. Ich nehme an, Sie sind sich der Probleme mit dem naiven Senden von Bytes bereits bewusst (wie potentielle Endianness-Probleme oder Versionierung), aber ich erwähne sie nur für den Fall ^ _ ^.
Eine korrekt dimensionierte Struktur als nullkopierte Bytes kann mit stdlib
und einer generischen Funktion erstellt werden.
Im folgenden Beispiel gibt es eine wiederverwendbare Funktion namens any_as_u8_slice
anstelle von convert_struct
, da dies ein Dienstprogramm zum Umbrechen der Cast- und Slice-Erstellung ist.
Beachten Sie, dass bei der Frage nach converting gefragt wird. In diesem Beispiel wird eine schreibgeschützte Schicht erstellt, was den Vorteil hat, dass Sie den Speicher nicht kopieren müssen.
Hier ein Arbeitsbeispiel basierend auf der Frage:
%Vor%Hinweis 1) obwohl die Kisten von Drittanbietern in einigen Fällen besser sind, ist dies eine so primitive Operation, dass es nützlich ist, in Rust zu wissen.
Hinweis 2) zum Zeitpunkt des Schreibens (Rust 1.15) gibt es keine Unterstützung für const
-Funktionen. Sobald dies der Fall ist, wird es möglich sein, in ein Array fester Größe anstelle eines Slices zu werfen.
Hinweis 3) Die Funktion any_as_u8_slice
ist mit unsafe
gekennzeichnet, da alle Füllbytes in struct
nicht initialisierter Speicher sein können (undefiniertes Verhalten).
Wenn es einen Weg gäbe, um sicherzustellen, dass die Eingabeargumente nur Strukturen verwenden, die #[repr(packed)]
sind, dann ist dies der Fall könnte sicher sein.
Ansonsten ist die Funktion relativ sicher, da sie einen Pufferüberlauf verhindert, da die Ausgabe schreibgeschützt ist, eine feste Anzahl von Bytes hat und ihre Lebensdauer an die Eingabe gebunden ist.
Wenn Sie eine Version wünschen, die% zurückgibt co_de%, das wäre ziemlich gefährlich, da das Ändern leicht inkonsistente / beschädigte Daten erzeugen könnte.
Tags und Links rust