|
Boost Users : |
Subject: Re: [Boost-users] [statechart] [spirit] OSI delimited message framing
From: Michael Caisse (mcaisse-lists_at_[hidden])
Date: 2013-06-19 13:27:04
On 06/19/2013 04:55 AM, Michael Powell wrote:
> Hello,
>
> I need to design a delimited message framing for TCP/IP sockets,
> probably using Asio to facilitate transport. Then build an OSI layer 7
> application vernier to handle framing.
>
> I've dabbled a bit with Spirit and cooked up a couple of "simple"
> micro grammars throughout the code base. In a sense, I could see a
> delimited message framing strategy being a grammar of sorts, but this
> seems somewhat complex for a grammar to handle when you consider the
> overhead of verifying pass/fail (message or not a message), plus
> extracting the message within the delimiters.
>
> Or, more likely approach the problem with statechart in mind. I've
> dealt with framed messages in the past more like this. One state is
> the escape byte, which can be followed by SOM, EOM, or another
> true-escape-byte (intended message byte). Plus other fields like
> message type, sub-type, how to handle payload, arguments, and so
> forth.
>
> Anyone else dealt with things like this before? With Spirit? With Statechart?
>
Hi Michael -
We write a lot of communication layers for both internal and client use.
One approach is to use use Spirit Qi/Karma to act as a translator. It
takes data objects in and produces byte streams (Karma) or takes a byte
stream in and produces objects (Qi). We use Asio for the communication
layer and Spirit for the protocol layer. This can all be nicely wrapped
up in a generic objects.
Spirit is stack based and so interrupting mid stream and saving state
when partial messages are received can be tricky. The *answer* is to use
a coroutine (Boost.Context).
We have also used a statemachine approach but prefer to use MSM for
protocol machines. It is much faster.
Just to add a bit more to the discussion:
message =
omit[ *( !som >> byte_ ) ] // sync stream to start of msg
>> som // start of msg rule
>> *( byte_ - eom ) // put your rule here
>> eom // read end of msg
;
The version above could synthesize a std::vector<unit8_t> for example.
You could have it parse the various message types or some generic
structure (16-bit command followed by N-byte payload).
I hope this gives you some thoughts.
michael
-- Michael Caisse ciere consulting ciere.com
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net