使用erlang实现简单的二进制通信协议
最近实现的一种简单的协议以及工具,主要用于客户端服务端通讯传输二进制数据时,协议的解包与封包,具体如下:
首先定义协议的格式,主要由三部分组成:
数据长度(数据部分长度+协议号长度):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实现简单的二进制通信协议的更多相关文章
- Erlang 位串和二进制数据
http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=25876834&id=3300393 因为在本人工作中,服务端Erla ...
- 转载:【原译】Erlang构建和匹配二进制数据(Efficiency Guide)
转自:http://www.cnblogs.com/futuredo/archive/2012/10/19/2727204.html Constructing and matching binarie ...
- ejabberd,erlang,简单看了一下,总结一下,很肤浅
本来也没打算深入学习erlang,就是看一下他们的大概思路erlang每个自定义函数都能注册成进程,每个节点通过erl -name 'name@ip'.进去后,可以直接做远程调用,节点之间就靠一个连接 ...
- erlang的简单模拟半包的产生
gen_tcp:linsten()/2使用的是{packet,2/4/8},则gen_tcp模块在接受或者发送时自动除去包头或者自动加上包头. 本例中使用的是{packet,0}. -module( ...
- 使用Erlang实现简单的排序算法:快速排序,冒泡排序,插入排序
[排序算法] -module(sort). -compile(export_all). %%快速排序 qsort([]) -> []; qsort([Pivot|T]) -> qsort( ...
- erlang二进制
在Erlang中写处理二进制数据的代码是洋溢着幸福感的,它对于二进制强大的表现力甚至能让你忘掉了它种种不便,今天我们说说Erlang的二进制数据处理. Erlang中bit string代表无类型的内 ...
- 转载: Erlang Socket解析二进制数据包
转自:http://www.itkee.com/developer/detail-318.html 今天在家里闲来无事,实践了一下Erlang的Socket的功能.记录一下在过程中遇到的一些问题,以及 ...
- erlang中通过ip和子网掩码,计算地址范围 【二进制和十进制的转换】
在程序中,难免用的二进制和十进制之间的转换.遇到一个场景,通过ip和子网掩码,计算地址范围. 而地址范围为:网络地址+1—— 广播地址 -1 . 网络地址即ip和子网掩码的与的位运算.广播地址为:网 ...
- erlang二进制数据垃圾回收机制
erlang二进制数据在内存中有两种存在形式,当数据大小不到 64 bytes,就直接存在进程堆内.假设超过了64 bytes.就被保存到进程外的共享堆里,能够给节点内全部进程共享. erlang有两 ...
随机推荐
- python 循环队列的实现
最近在做一个东西的时候发现需要用到循环队列,实现先进先出(FIFO),不断往里面添加数据,当达到某个限定值时,最先进去的出去,然后再添加.之后需要对队列里面的内容进行一个筛选,作其他处理.首先我想到了 ...
- Hive表中Partition的创建
作用: 在Hive Select查询中一般会扫描整个表内容,会消耗很多时间做没必要的工作.有时候只需要扫描表中关心的一部分数据,在对应的partition里面去查找就可以,减少查询时间. 1. 创建表 ...
- linux常用命令:iostat 命令
Linux系统中的 iostat 是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视.它的特点是汇报磁盘活动统计情况,同时也会 汇报出CPU使用情况 ...
- linux 中的定时任务crontab使用方法
linux 中的定时任务crontab使用方法: 切换到root用户,sudo su root (可以设置成不需要输入密码) sudo su - (需要输入当前帐号的密码才能进入.) crontab ...
- Js基础知识2-对象、对象属性全解
Object对象 Object对象包含如下属性和方法,也就意味着一切对象(函数也是对象)都包含如下方法. 每种方法和属性在不同的对象中有不同的作用,并不是每种对象都有使用每个方法的必要. 下面是Obj ...
- pyDay2
内容来自廖雪峰的官方网站 1.dict 为什么dict查找速度这么快?因为dict的实现原理和查字典是一样的.假设字典包含了1万个汉字,我们要查某一个字,一个办法是把字典从第一页往后翻,直到找到我们想 ...
- spring mybatis 3.2调用mysql存储过程返回多结果集(完整、亲测、可用)
最近,有个开发提了个需求,希望中间件支持调用mysql存储过程时支持多结果集返回,因为某些原因我们使用了不少的存储过程,很多复杂的逻辑目前来看交互非常的多,所以从当前的现状来说,这个需求还是蛮合理的. ...
- 本地连接VM virtualBox ubuntu16.04 中的Mysql数据库
1.打开mysql配置文件vim /etc/mysql/mysql.conf.d/mysqld.cnf 将bind-address = 127.0.0.1注销 2.重启ubuntu数据库 3. ...
- div转svg svg转canvas svg生成图片及图片下载 分享
链接来自:http://blog.csdn.net/u010081689/article/details/50728854
- Python3基础 list reversed 列表逆转并输出
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...