[erlang-questions] segments of variable length

Gamoto <>
Sat Apr 4 14:03:37 CEST 2009


Thank you Per. That was the good solution. I understood my faults now ...
John

hat is because you are sending the following binary encoded term:
"$AVRMC,1234,151736" and you are matching that to {<<H,U,T>>} and a string does not match a one-tuple with a three byte binary as only element.

what you want is probably something like this:

-module(aa).
-define(X,<<131,107,0,18,36,65,86,82,77,67,44,49,50,51,52,44,49,53,49,55,51,54>>).
-export([start/0]).

start() ->
  case string:tokens(binary_to_term(?X), ",") of
    [H,U,T] ->
      io:format("Header = ~s~n",[H]),
      io:format("Unit ID = ~s~n",[U]),
      io:format("Time = ~s~n",[T])
   end.

The question is if the wire protocol isn't given this is not the easiest way to have two Erlang nodes talk. It would be far easier to say that the nodes should be sending binary encoded three-tuples to each other then you'd have something like this:

-module(ab).
-define(X, term_to_binary({"$AVRMC", 1234, 151736})).
-export([start/0]).

start() ->
  case binary_to_term(?X) of
    {H,U,T} ->
      io:format("Header = ~s~n",[H]),
      io:format("Unit ID = ~p~n",[U]),
      io:format("Time = ~p~n",[T])
   end.
  
Note that in this case Unit ID and Time would be numbers rather than strings.

None of the code above has actually been tested so it might not compile.

Per



2009/4/3 Gamoto <>

-module(aa).
-define(X,<<131,107,0,18,36,65,86,82,77,67,44,49,50,51,52,44,49,53,49,55,51,54>>).
-export([start/0]).

start()->
  case binary_to_term(?X) of
           {<<H,U,T>>}->
            io:format("Header = ~s~n",[H]),
            io:format("Unit ID = ~s~n",[U]),
            io:format("Time = ~s~n",[T])
       end.

This gives me an error.
I was waiting for
Header = $AVRMC
Unit ID = 1234
Time =  151736

The most important for me is to obtain H,U and T

>
>
>> I receive from several machines messages and I would like to extract data.
>> My first approach was:
>>
>> handler(Data)->
>>     case Data of
>>         <>
>>         etc...
>>
>> My problem is that some segment have a fixed length (header, Status) and some
>> others a variable length (Time <= 6 bytes, UnitID <= 8 bytes).
>> My approach is bad. I thought to do:      Segments = string:tokens(Data,",")
>> This separates the segments but I don't have their name
>> (header,unitid,time,status) !
>> Could you advice me a better approach. My goal is to check each segment and make
>> actions according to their values.
>
>You need to define a message format such that the required information is present to determine how to parse the rest of the message. This isn't really an erlang-specific problem but erlang is very good at supporting this.
>
>As an example you could use erlang:term_to_binary() and binary_to_term() for the message encoding on the wire. binary_to_term() might fail if the message is incomplete. This is where the {packet, N} inet options for connect/listen come in, eg. {packet,2} will only return complete messages; the length header is added automatically on send and stripped on receive so you only need to do, eg.
>
>gen_tcp:send( Sock, term_to_binary( MessageTerm ) )
>
>and if you receive {tcp, Sock, Data}, then it is safe to call
>
>MessageTerm = binary_to_term(Data)
>
>Check out the inet module documentation. There are lots of useful options.
>
>Hope that is useful
>
>--
>  Rich
>
>
>      The new Internet Explorer 8 optimised for Yahoo!7: Faster, Safer, Easier.

_______________________________________________
erlang-questions mailing list

http://www.erlang.org/mailman/listinfo/erlang-questions
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20090404/0fef46fc/attachment.html>


More information about the erlang-questions mailing list