Erlang位语法模式匹配在shell中有效,但不能作为传递的参数



我正在尝试制作一个简单的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/17/12 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.  

没有用。非常感谢您的帮助。

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

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

是CCD_ 1错误,并且来自于模式与来自RHS的值不匹配的显式CCD_。rcv_loop/1的代码中没有=。这意味着您正在运行的循环不是此代码。因此,有一些问题需要问:

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

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

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

像斑点Alexey Kachayevio: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]).

我想明白了(有点)。我一直在eclipse中的erlide中进行这项工作,这对其他部分都很好。我试着从erlshell编译它,结果很好。eclipse表示源代码的方式或调用erlang编译器和shell的方式肯定有一些细微的不同。我会在erlide.org上接受它。谢谢你的帮助!

相关内容

最新更新