Boost logo

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