使用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 星号*使用方法
			1.乘号 2.表示倍数 def T(msg,time=1): print((msg+',,')*time) >>>T('hi',3) hi,,hi,,hi 3.单个星号* --1-- ... 
- 如何制作Windows镜像
			1.在https://msdn.itellyou.cn/网站中下载(使用迅雷)Windows2003R2 中文版ISO 2.使用qemu-img create命令创建一个空的 后缀为.img的文件 q ... 
- web测试项目总结
			一.输入框 1.字符型输入框: (1)字符型输入框:英文全角.英文半角.数字.空或者空格.特殊字符“~!@#¥%……&*?[]{}”特别要注意单引号和&符号.禁止直接输入特殊字符时,使 ... 
- web前端----jQuery基础语法
			一.jQuery基础1.为什么要用jquery? 写起来简单,省事,开发效率高,兼容性好2.什么是jQuery? jQuery是一个兼容多浏览器的JavaScript库(类似python里面的模块)3 ... 
- 干货:Java并发编程必懂知识点解析
			本文大纲 并发编程三要素 原子性 原子,即一个不可再被分割的颗粒.在Java中原子性指的是一个或多个操作要么全部执行成功要么全部执行失败. 有序性 程序执行的顺序按照代码的先后顺序执行.(处理器可能会 ... 
- Django框架之跨站请求伪造
			跨站请求伪造(英语:Cross-site request forgery),也被称为one-click attack或者session riding,通常缩写为CSRF或者XSRF, 是一种挟制用户在 ... 
- linux下精确替换某个字符串
			1.linux下精确替换某个字符串 sed -i 's/\<old\>/new/g' filename.txt 2.举例: 2.1有个文件名为filename.txt,内容如下: newd ... 
- 九数组分数|2015年蓝桥杯B组题解析第五题-fishers
			九数组分数 1,2,3...9 这九个数字组成一个分数,其值恰好为1/3,如何组法? 下面的程序实现了该功能,请填写划线部分缺失的代码. #include <stdio.h> void t ... 
- Linux deepin 中Jetbrain Idea等软件中文显示异常
			解决方案:安装常用的中文字体 # 文鼎宋体[推荐] sudo apt install fonts-arphic-uming # 文鼎楷体[推荐] sudo apt install fonts-arph ... 
- json获取元素数量
			var keleyijson={"plug1":"myslider","plug2":"zonemenu"} funct ... 
