我正在尝试制作一个简单的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上接受它。谢谢你的帮助!