Erlang的模式匹配用来处理二进制数据可谓是得心应手。不仅直观,而且超乎想象的简单。在C++中,处理二进制数据首先要管理缓冲区。然后再按字节进行操作,如果要处理的数据不是按字节对齐,则需要进行位移等操作。操作过程复杂又难懂,如果再没有注释,那对于维护这段代码的人来说简直就是噩梦。例如:操作一串保存了RGB颜色值序列的二进制串,在C++中要这样操作:

struct RGB
{
char R;
char G;
char B;
}; vector<RGB> rgbVector;
for(int i = ; i < pixelsLen; i = i + )
{
RGB rgb;
rgb.R = pixels[i];
rgb.G = pixels[i + ];
rgb.B = pixels[i + ];
rgbVector.push_back(rgb);
}

  首先要定义RGB结构,假设RGB数据流保存在pixels指向的地址中,然后通过循环解析出相应的RGB值,然后保存在数组中。而实现同等功能的Erlang却只需要一行就搞定,如下:

Pixels = <<213,45,132,64,76,0,0,234,32,15>>.
RGB = [ {R,G,B} || <<R:8,G:8,B:8>> <= Pixels ].

  是不是很简单,而且上面所举的例子中,RGB的值刚好是一个字节,所以在C++中处理方式相对比较简单。下面看一个更复杂的实例,这个例子在Erlang官方文档中有介绍,你可以戳这里.这是一个解析IP数据包头的例子(如果不了解IP包头戳这里),在Erlang中只需要这样:

-define(IP_VERSION, 4).
-define(IP_MIN_HDR_LEN, 5).
DgramSize = size(Dgram),
case Dgram of
<<?IP_VERSION:4, HLen:4, SrvcType:8, TotLen:16,
ID:16, Flgs:3, FragOff:13,
TTL:8, Proto:8, HdrChkSum:16,
SrcIP:32,
DestIP:32, RestDgram/binary>> when HLen>=5, 4*HLen=<DgramSize ->
OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN),
<<Opts:OptsLen/binary,Data/binary>> = RestDgram,
...
end.

  看到这段代码你是不是很容易得就明白了,它要干什么,各种值的位置、占用的空间大小以及所代表的意思都一目了然,看着真的是有一种心旷神怡的感觉。我第一次看到这样的处理方式时,我很激动,原来处理二进制数据可以如此简单直观。虽然简单易懂,但是我还是要在这里简单的介绍一下,首先通过size函数获取整个IP数据包的长度。然后对整个数据包进行二进制模式匹配。根据IP包头的格式,0-3位是协议版本号,对于IPV4来说这里应该是4,所以在模式匹配的时候直接<<4:4, Rest/binary>>就可以匹配到版本号了。上面的例子中把4定义成一个宏。接下来的4-7位是IP首部的长度。后面的我就不详细介绍了,具体IP头部参考这里。我在这里举这个例子并不是为了真的用Erlang去解析IP包,仅仅是为了说明Erlang解析二进制的优点。

  最后给一个我现在游戏服务器中包头的解析。包头由16位的包长度和16位的消息码组成,总共4个字节。解析的方式如下:
<<DataLen:16,Command:16,RData/binary>> = Data

  其中Data是原始数据包,DataLen是包长度,Command是消息码,RData是包体。当然在实际项目中还要考虑粘包,半包以及相应的错误处理部分,这里仅仅提供了二进制模式匹配的方式。

Erlang二进制模式匹配的更多相关文章

  1. erlang二进制数据垃圾回收机制

    erlang二进制数据在内存中有两种存在形式,当数据大小不到 64 bytes,就直接存在进程堆内.假设超过了64 bytes.就被保存到进程外的共享堆里,能够给节点内全部进程共享. erlang有两 ...

  2. erlang二进制

    在Erlang中写处理二进制数据的代码是洋溢着幸福感的,它对于二进制强大的表现力甚至能让你忘掉了它种种不便,今天我们说说Erlang的二进制数据处理. Erlang中bit string代表无类型的内 ...

  3. erlang 二进制中 拼接 变量或者函数 报错

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVsAAACiCAIAAABgR/nfAAAM5ElEQVR4nO2dzZrcKBJF9Zjd/tnOdN

  4. elixir二进制模式匹配

    for << << b1::size(2), b2::size(3), b3::size(3) >> <- "hello" >> ...

  5. erlang二进制的难理解的地方,有点神奇

    40> <<A:16>> = <<1,2>>.<<1,2>>41> <<B:16/bits>> ...

  6. Erlang入门(一)

    读erlang.org上面的Erlang Course四天教程1.数字类型,需要注意两点1)B#Val表示以B进制存储的数字Val,比如 7> 2#101.5 二进制存储的101就是10进制的5 ...

  7. 76个值得你注意的erlang编程习惯

    http://www.tuicool.com/articles/ZNzuyu 前言 学习Erlang的时候在书的留白处随手记录了一些东西,还有一些记录在了demo的注释里面,今天抽时间整理出来了一部分 ...

  8. Erlang 杂记

    学习Erlang的时候在书的留白处随手记录了一些东西,还有一些记录在了demo的注释里面,今天抽时间整理出来了一部分,分享一下. Erlang的设计哲学是为每一个独立的事件创建一个新进程. Erlan ...

  9. 【译】构造和匹配二进制(Efficiency Guide)

    可以通过以下方式有效地构建二进制: my_list_to_binary(List) -> my_list_to_binary(List, <<>>). ​ my_list ...

随机推荐

  1. GridView从行寻找到该控件,以及从该控件获知该行

    原文发布时间为:2008-08-01 -- 来源于本人的百度文章 [由搬家工具导入] GridView从行寻找到该控件: protected void Button3_Click(object sen ...

  2. java打包python到exe文件

    最近想把写的python代码打包,以供没用安装python环境的同事使用,需求如下: 无python环境也可执行 文件尽量少,不要太乱 程序体积尽量小 如果需要更新的话重复类库不用更新 采用方案如下: ...

  3. hdu 3605 /状态合并最大流

    题意:N个人去m个星球,给出n个人可以去哪些星球的01矩阵.求是否能满足所有人都去.(n到10万,m<=10) 一看,起先一瞬间就建图,准备秒了,人向星球连边,直接最大流判断是否为n,提交超时. ...

  4. react-highcharts

    import ReactHighcharts from'react-highcharts'; class SummaryLeft extends Component { render () {var ...

  5. 关于django rest framework里token auth的实现及答疑

    http://stackoverflow.com/questions/14838128/django-rest-framework-token-authentication ============= ...

  6. 浅谈APP的分享功能,有时候社交裂变形式比内容更“重要”

    回顾2018年的移动互联网,“社交裂变”“下沉”等成为年度关键词.一方面我们可以看到社交裂变助推用户增长,另一方面我们也看到了以拼多多.趣头条为代表的互联网企业对于社交裂变模式表现出的空前关注度.作为 ...

  7. 转载:P2P技术原理及应用(2)

    转载allen303allen的空间 在Gnutella网络中存在以下问题: 冗余消息多,对带宽的消耗存在一定的浪费.Gnutella网络协议采用泛洪式(Flooding)消息传播机制,这种消息传播机 ...

  8. 四个很好的开源app项目

    Open Source and the iOS App Store Today, we are open-sourcing 4 iOS apps: ThatInbox, an email client ...

  9. docker 如何清理垃圾呢

    应用容器在宿主机上长期运行,应用实例启停容器,会产生大量的停止的容器,无容器使用的数据卷.网络配置,无容器依赖的镜像,这些垃圾日积月累,会影响到宿主机的运行状态,造成机子卡顿等现象.因此,需要对这些宿 ...

  10. 在谈MVP之前,你真的懂MVC吗?

    最近看到很多文章在谈论MVP或者MVVM模式的,但其实无论MVP还是MVVM都只是MVC模式的一种变种.而如果你对MVC的设计理念都还没有理解透彻,那么即使换成MVP亦或MVVM也不可能让你杂乱不堪的 ...