原创作者: AvinDev
阅读:2673次
评论:1条
更新时间:2011-06-01
在Erlang里面,Binary支持强大的模式匹配,这为编写网络通讯程序提供了便利。
比如一个协议串,格式如下
HEADER(2 Bytes) ID (1 Byte) MESSAGE(10 Bytes)
可以这样匹配
<<Header:16, Id:8, Message:10/binary-unit:8>>
有一些协议,头部是接下来数据的长度,这样就更简单了
<<Size:8, Content:Size/binary-unit:8>>
一个IPV4的头部可以这样表示
具体应用
比如定义了一个协议,头部2字节为长度,接下来是Body。要接收这样一个包,有可能会不全,也有可能2个包一起接收了,这时候可以这样做:
这个解决方案还是相当笨拙的,Erlang本身有更好的解决方案,这里只是为了演示。
比如一个协议串,格式如下
HEADER(2 Bytes) ID (1 Byte) MESSAGE(10 Bytes)
可以这样匹配
<<Header:16, Id:8, Message:10/binary-unit:8>>
有一些协议,头部是接下来数据的长度,这样就更简单了
<<Size:8, Content:Size/binary-unit:8>>
一个IPV4的头部可以这样表示
引用
<<Version:4, IHL:4, TypeOfService:8, TotalLength:16,
Identification:16, FlagX:1, FlagD:1, FlagM:1,
FragmentOffset:13, TTL:8, Protocol:8,
HeaderCheckSum:16, SourceAddress:32,
DestinationAddress:32, Rest/binary>> = Packet.
Identification:16, FlagX:1, FlagD:1, FlagM:1,
FragmentOffset:13, TTL:8, Protocol:8,
HeaderCheckSum:16, SourceAddress:32,
DestinationAddress:32, Rest/binary>> = Packet.
具体应用
比如定义了一个协议,头部2字节为长度,接下来是Body。要接收这样一个包,有可能会不全,也有可能2个包一起接收了,这时候可以这样做:
loop(Socket, Buffer) -> RecvBinary = gen_tcp:recv(Socket,0), Binary = list_to_binary(binary_to_list(Buffer) ++ binary_to_list(RecvBinary)), case Binary of <<Size:16, Body:Size/binary-unit:8, Remaining/binary>> -> handleMessage(Body), loop(Socket, Remain); <<_/binary>> -> loop(Socket, Binary) end.
这个解决方案还是相当笨拙的,Erlang本身有更好的解决方案,这里只是为了演示。
1 楼 erlangguy 2011-03-24 10:15