最近实现的一种简单的协议以及工具,主要用于客户端服务端通讯传输二进制数据时,协议的解包与封包,具体如下:
首先定义协议的格式,主要由三部分组成:
        数据长度(数据部分长度+协议号长度):4个字节
        协议号:2个字节
        数据部分:2进制数据
数据部分如果是字符串需要先计算字符串的长度,占2个字节,之后再紧跟字符串内容,
以上三个部分构成一个完整的数据包,每次客户端服务端将数据进行以上格式的封包解包进行通信。
下面是对一个协议号为10000的协议进行封包的例子:
客户端向服务端发送了三个数据:角色rid(4个字节),服务器srv_id(字符串),消息msg(字符串),
根据以上定义的协议的打包方式如下,定义一个erlang函数:

pack(cli, 10000, {Rid, Srv_id, Msg}) ->
Data = <<Rid:32, byte_size(Srv_id):16, Srv_id/binary, byte_size(Msg):16, Msg/binary>>,
Packet = <<(byte_size(Data) + 2):32, 10000:16, Data/binary>>,
{ok, Packet}.

之后客户端可能通过socket的方式将二进制数据包发送给服务端了。

假设服务器收到数据,开始对数据包进行解析,
 P0表示一个完整的包的数据部分,且是上面客户端打包的数据,协议号为10000号,接下来就是将P0进行解包,
 对此我写了一个模块lib_proto,专门来解析二进制数据包。下面的解析过程就是针对协议号为10000的数据包进行解析:

unpack(srv, 10000, P0) ->
{Rid, P1} = lib_proto:read_uint32(P0),
{Srv_id, P2} = lib_proto:read_string(P1),
{Msg, _P3} = lib_proto:read_string(P2),
{ok, {Rid, Srv_id, Msg}}.

通过上面的方式就能将数据包解析出来,得到各个字段的值。
下面是lib_proto的部分实现:

read_uint32(B0) when is_binary(B0)
andalso byte_size(B0) >= 4 ->
<<Int32:32, B1/binary>> = B0,
{Int32, B1};
read_uint32(_B0) -> error. read_string(B0) when is_binary(B0)
andalso byte_size(B0) >= 2 ->
<<Len:16, B1/binary>> = B0,
case byte_size(B1) >= Len of
true ->
<<String:Len/binary, B2/binary>> = B1,
{String, B2};
false ->
error
end;
read_string(_B0) -> error.

以上就是使用erlang进行二进制数据包的解包与封包的应用,应该说erlang生来就对处理二进制数据进行了很好的封装,
个人只是在此基础上进行简单应用而已。

使用erlang实现简单的二进制通信协议的更多相关文章

  1. Erlang 位串和二进制数据

    http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=25876834&id=3300393 因为在本人工作中,服务端Erla ...

  2. 转载:【原译】Erlang构建和匹配二进制数据(Efficiency Guide)

    转自:http://www.cnblogs.com/futuredo/archive/2012/10/19/2727204.html Constructing and matching binarie ...

  3. ejabberd,erlang,简单看了一下,总结一下,很肤浅

    本来也没打算深入学习erlang,就是看一下他们的大概思路erlang每个自定义函数都能注册成进程,每个节点通过erl -name 'name@ip'.进去后,可以直接做远程调用,节点之间就靠一个连接 ...

  4. erlang的简单模拟半包的产生

     gen_tcp:linsten()/2使用的是{packet,2/4/8},则gen_tcp模块在接受或者发送时自动除去包头或者自动加上包头. 本例中使用的是{packet,0}. -module( ...

  5. 使用Erlang实现简单的排序算法:快速排序,冒泡排序,插入排序

    [排序算法] -module(sort). -compile(export_all). %%快速排序 qsort([]) -> []; qsort([Pivot|T]) -> qsort( ...

  6. erlang二进制

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

  7. 转载: Erlang Socket解析二进制数据包

    转自:http://www.itkee.com/developer/detail-318.html 今天在家里闲来无事,实践了一下Erlang的Socket的功能.记录一下在过程中遇到的一些问题,以及 ...

  8. erlang中通过ip和子网掩码,计算地址范围 【二进制和十进制的转换】

    在程序中,难免用的二进制和十进制之间的转换.遇到一个场景,通过ip和子网掩码,计算地址范围. 而地址范围为:网络地址+1—— 广播地址 -1 .  网络地址即ip和子网掩码的与的位运算.广播地址为:网 ...

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

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

随机推荐

  1. Python:re.sub()实现字符串替换

    re.sub的功能 re是regular expression的缩写,表示正则表达式:sub是substitude的缩写,表示替换 re.sub是正则表达式的函数,实现比普通字符串更强大的替换功能 s ...

  2. mysql创建外链失败1005错误解决方法

    mysql创建外链失败1005错误解决方法 错误号:1005错误信息:Can't create table 'webDB.#sql-397_61df' (errno: 150)解决方法 错误原因有四: ...

  3. (iOS)关于键盘遮挡textfield问题

    记录一下自己经常遇到问题.使用textfield(textview).当输入框位置比较靠下时,弹出的键盘会遮挡输入框,这是就需要动态移动输入框编辑状态时self.view的位置, 自己经常用的方法有两 ...

  4. LWIP裸机环境下实现TCP与UDP通讯(转)

    源: LWIP裸机环境下实现TCP与UDP通讯

  5. MySQL Crash Course #15# Chapter 23. Working with Stored Procedures

    以前写过类似的东西,用来自动生成数据. 你可以将 Stored Procedure 理解为可以重复使用的批处理文件. Stored Procedure 非常有用,我们应该尽可能地去使用它. 那么,应用 ...

  6. 深入理解kafka

    摘自: <kafka权威指南> 集群间成员关系 Kafka 使用Zoo keeper 来维护集群成员的信息.每个broker 都有一个唯一标识符,这个标识符可以在配置文件里指定,也可以自动 ...

  7. updateByPrimaryKeySelective更新失败

    问题:使用Mybatis中Mapper内置方法updateByPrimaryKeySelective更新失败. 发现:控制台打印出来的sql语句发现where条件出现所有属性. 解决:映射的实体类没有 ...

  8. Python3基础 lambda 简单示例

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  9. Python3基础 if嵌套示例

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  10. Python3基础 str format 位置参数与关键字参数

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...