Erlang Bit语法模式匹配在shell中工作,但不能作为传递参数

时间:2012-09-07 03:13:19

标签: parsing syntax erlang udp bit

我正在尝试制作一个简单的UDP数据包解码器。

packet_decoder(Packet)->
<<Opts:8,MobIdLength:8,MobId:64,MobIdType:8,MgeType:8,SeqNum:16,Rest/binary>> = Packet,
io:format("Options:~p~n",Opts),
io:format("MobIdLength:~p~n",MobIdLength),
io:format("MobId:~p~n",MobId),
io:format("MobIdType:~p~n",MobIdType),
io:format("MgeType:~p~n",MgeType),
io:format("SeqNum:~p~n",SeqNum).

数据包由接收循环传递:

rcv_loop(Socket) ->
inet:setopts(Socket, [{active, once}, binary]),
io:format("rcvr started:~n"),
receive
    {udp, Socket, Host, Port, Bin} ->
        packet_decoder(Bin),
        rcv_loop(Socket)
end.

我一直在接受(在美国东部时间9月7日9:30编辑错误之后):

** exception error: no match of right hand side value 
                    <<131,8,53,134,150,4,149,0,80,15,1,2,1,2,0,16,80,71,115,
                      52,80,71,115,53,24,63,227,197,211,...>>
     in function  udp_server:packet_decoder/1
        called as udp_server:packet_decoder(<<131,8,53,134,150,4,149,0,80,15,
                                              1,2,1,2,0,16,80,71,115,52,80,71,
                                              115,53,24,63,227,197,...>>)
     in call from udp_server:rcv_loop/1 
     in call from udp_server:init/0 

如果我在Erlang shell中创建与二进制文件相同的变量,即

Packet = <<131,8,53,134,150,4,149,0,80,15,1,2,1,2,0,16,80,71,115,52,80,71,115,53,24,63,227,197,211,228,89,72,0,0,0,0,0,0,0,16,0,5,5,32,1,4,255,159,15,18,28,0,34,62,2,0,0,0,0,0,0,0,47,67>>.

<<Opts:8,MobIdLength:8,MobId:64,MobIdType:8,MgeType:8,SeqNum:16,Rest/binary>> = Packet.

它运作得很好。是否有一些微妙的传递给我失踪的功能?我已经尝试过我认为的一切(除了正确的方法)。我尝试设置类型和大小。我也试过了

<<Rest/binary>> = Packet.  

无济于事。任何帮助非常感谢。

3 个答案:

答案 0 :(得分:2)

运行代码时出现的错误与您的代码不符。你得到的错误:

** exception error: no match of right hand side value ...

badmatch错误,来自显式=匹配,其中模式与RHS的值不匹配。 =的代码中没有rcv_loop/1。这意味着您运行的循环不是此代码。所以有一些问题要问:

  • 当您重新编译包含rcv_loop/1的模块时,您是否重新启动了循环以便运行新代码?这不是自动完成的。
  • 您确定要加载/运行您认为自己的代码吗?我知道这个问题听起来很愚蠢,但是在一个版本的代码上工作并加载另一个版本非常容易,而且并不罕见。你需要把路径弄好。

关于你的代码提到的其他事情不会给出这个错误。对io:format/2的调用是错误的,但在您对io:format/2进行实际调用时会导致错误。像你一样使用变量Socket不是错误,它只是意味着你只想从那个套接字接收UDP数据包。

答案 1 :(得分:0)

编辑:我的回答的第一部分是完全错误的,所以为了不误导,我删除了它。

喜欢发现 Alexey Kachayev io:format作为列表的第二个参数,所以:

packet_decoder(Packet)->
<<Opts:8,MobIdLength:8,MobId:64,MobIdType:8,MgeType:8,SeqNum:16,Rest/binary>> = Packet,
io:format("Options:~p~n",[Opts]),
io:format("MobIdLength:~p~n",[MobIdLength]),
io:format("MobId:~p~n",[MobId]),
io:format("MobIdType:~p~n",[MobIdType]),
io:format("MgeType:~p~n",[MgeType]),
io:format("SeqNum:~p~n",[SeqNum]).

答案 2 :(得分:0)

我想通了(有点)。我曾经在日食中的erlide工作,这对于所有其他部分都很好。我尝试从erl shell编译它,它工作正常。 eclipse表示源的方式或它调用erlang编译器和shell的方式必须有一些细微的差别。我将与erlide.org一起讨论。谢谢你的帮助!