Erlangバイナリモードマッチング

3881 ワード

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は、次のように1行で完了します.
Pixels = <<213,45,132,64,76,0,0,234,32,15>>.

RGB = [ {R,G,B} || <<R:8,G:8,B:8>> <= Pixels ].

簡単なのではないでしょうか.また、上記の例では、RGBの値はちょうど1バイトなので、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ビットはプロトコルバージョン番号であり、IPV 4にとってここは4であるはずなので、モードマッチング時に直接<<4:4、Rest/binary>>でバージョン番号にマッチングできます.上記の例では4を1つのマクロとして定義する.次の4-7ビットはIPヘッダの長さです.後の私は詳しく紹介しません.具体的なIPヘッダはここを参照してください.私がここでこの例を挙げるのは、本当にErlangでIPパケットを解析するためではなく、Erlangがバイナリを解析する利点を説明するためだけです.
最後に、私の今のゲームサーバーのパッケージの解析をあげます.パケットヘッダは、16ビットのパケット長と16ビットのメッセージコードからなり、合計4バイトである.解析の方法は次のとおりです.
<<DataLen:16,Command:16,RData/binary>> = Data

ここで、Dataは元のパケットであり、DataLenはパケット長であり、Commandはメッセージコードであり、RDataはパケット体である.もちろん、実際のプロジェクトでは、粘着パケット、半パケット、および対応するエラー処理部分も考慮され、ここではバイナリモードマッチングのみが提供される.