1

我正在尝试制作一个简单的 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/12 9:30 EST):

** 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.  

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

4

3 回答 3

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 数据包。

于 2012-09-07T08:09:20.627 回答
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]).
于 2012-09-07T06:48:23.253 回答
0

我想通了(有点)。我一直在 erlide in eclipse 中进行此工作,这对所有其他部分都运行良好。我尝试从 erl shell 编译它,它工作正常。eclipse 表示源代码的方式或它调用 erlang 编译器和 shell 的方式肯定有一些细微的差别。我将与 erlide.org 一起讨论。谢谢您的帮助!

于 2012-09-11T12:08:12.157 回答