zoukankan      html  css  js  c++  java
  • Erlang二进制模式匹配

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

    struct RGB
    {
        char R;
        char G;
        char B;
    };
    
    vector<RGB> rgbVector;
    for(int i = 0; i < pixelsLen; i = i + 3)
    {
        RGB rgb;
        rgb.R = pixels[i];
        rgb.G = pixels[i + 1];
        rgb.B = pixels[i + 2];
        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是包体。当然在实际项目中还要考虑粘包,半包以及相应的错误处理部分,这里仅仅提供了二进制模式匹配的方式。

  • 相关阅读:
    Junit单元测试
    win7的6个网络命令
    WOJ1024 (POJ1985+POJ2631) Exploration 树/BFS
    WOJ1022 Competition of Programming 贪心 WOJ1023 Division dp
    woj1019 Curriculum Schedule 输入输出 woj1020 Adjacent Difference 排序
    woj1018(HDU4384)KING KONG 循环群
    woj1016 cherry blossom woj1017 Billiard ball 几何
    woj1013 Barcelet 字符串 woj1014 Doraemon's Flashlight 几何
    woj1012 Thingk and Count DP好题
    woj1010 alternate sum 数学 woj1011 Finding Teamates 数学
  • 原文地址:https://www.cnblogs.com/kiven-code/p/3758050.html
Copyright © 2011-2022 走看看