Ich versuche ein einfaches serielles Port-Protokoll zu implementieren. Es geht so:
0xff
empfangen wurde 0xff
angezeigt wird, auch wenn es nicht wie in der Mitte der Daten erwartet wird, bedeutet dies, dass ein neues Paket empfangen wird Ich kann dies implementieren, indem boost::asio::serial_port
mit boost::asio::read()
ein einzelnes Byte liest und dieses Byte verarbeitet, wenn es empfangen wird. Obwohl das funktioniert, habe ich mich gefragt, ob es einen "boost" -artigen Weg gibt, dies zu tun?
Ich habe boost::asio::read_until()
zum Lesen gelesen bis 0xff
, aber dann weiß ich nicht, wie ich die Daten verwerfen soll. Speichern der Daten in einem Puffer und dann nicht den Puffer verwenden scheint ein wenig verschwenderisch.
Ich kann boost::asio::read_until()
zum Lesen bis zum Ende des Pakets verwenden, aber dann muss MatchCondition
Zugriff auf den Puffer (den Header des Pakets) haben. Es scheint, dass MatchCondition
nur einen Iterator für das erste und letzte Byte erhält, das kürzlich empfangen wurde.
Auch die mit boost::asio::read()
empfangenen Daten landen in stream_buf
und ich muss die empfangenen Daten in ein Packet
-Objekt analysieren. Ich kann das in Packet
in einem separaten ParsePacket
-Objekt parsen oder irgendwie mit boost::asio
integrieren (etwas wie boost::asio::read(serial, myPacket);
, wobei myPacket
ein Packet
-Objekt ist)
Wenn 0xff
irgendwo in den empfangenen Daten gesehen wird, bedeutet dies, dass ein neues Paket gestartet wird. Wenn also 0xff
empfangen wird, muss es alle zuvor empfangenen Daten vergessen und ein neues Paket empfangen.
Ich plane die Verwendung asynchroner Operationen und das Hinzufügen von Timeouts.
Meine Frage ist also: Wo soll ich ein solches Protokoll implementieren? Oder allgemeiner, wo ein Protokoll mit boost::asio
implementiert werden soll. Ich suche nicht nach funktionierendem Code, sondern nach Ratschlägen darüber, wo das Protokoll implementiert werden soll und welche boost::asio
-Funktionalität zu verwenden ist.
Aktualisierung:
In diesem Fall wird keine Flusssteuerung (Hardware oder Software) verwendet.
Zunächst möchte ich Ihnen, wie @Autopulated in Kommentaren gezeigt hat, vor der Verwendung von Trennzeichen (Ihre 0xFF) in binären Protokollen warnen. Es ist eine gefährliche Technik (bringt viel Zweideutigkeit) und erfordert komplizierte Implementierungen. Selbst wenn Sie garantieren können, dass Ihre Daten keine 0xFF-Bytes enthalten, können Sie dies beim CRC-Feld nicht tun.
Ich würde empfehlen, sich nicht mit Trennzeichen zu beschäftigen und sich auf ein einfaches und vorhersagbares Binärprotokoll zu konzentrieren: [packet][packet]...
wo [packet] = [node address:X][data length:4][data:data length][CRC:1]
Das Senden solcher Pakete kann wie folgt aussehen:
%Vor%Empfangen:
%Vor%Bitte beachten Sie, dass in diesem Beispiel angenommen wird, dass beide Peers die gleiche Endgültigkeit haben.
Ich habe diesen Code hier geschrieben, also erwarte nicht, dass er richtig ist, benutze ihn nur als Idee.
Bei der Implementierung von Protokollen habe ich zuvor State-Maschinen sehr nützlich gefunden.
Obwohl ich asio
nicht verwendet habe, kann diese Technik hier anwendbar sein.
Diese können in C ++ als enum
, als Schleife und als switch
wie folgt implementiert werden:
Sie müssten mehr Flags hinzufügen, um Ihren Fortschritt im Protokoll zu verfolgen.
Sie können auch nach boost::statechart
suchen Implementieren der Zustandsmaschine.
Tags und Links c++ boost-asio protocols