关于lua扩展库lpack的使用指南

  • 最近在研究luasocket,准备用全部用lua的扩展库来实现一套轻量级框架,用来做一些工具、简单的游戏服务器,以及作为网络库用在cocos2dx中。
  • 完善的网络库必然会遇到粘包、半包的问题,luasocket也不例外,由于网络部分在lua,协议的制定和buff的解析都没有合适的方案,又不想在C++中来封装接口,后面在网上查了一些资料,发现lua也有一个二进制打包的扩展库——lpack,了解之后发现还是蛮好用的,就决定使用它来做buff解析,用以解决粘包、半包的问题。

  • 首先需要下载lpack的源码,地址是lpack的下载地址,然后解压,里面有lpack.c和makefile文件。
  • 然后是编译lpack,有两种方式来编译和初始化lpack 1、将lpack.c加到宿主程序的源码里面,然后在初始化lua的地方调用初始化函数: luaopen_pack(lua_state); 2、将lpack编译成dll(so),然后在lua里面调用: require("lpack")

  • 然后说一下lpack的接口,lpack扩展库提供了两个接口,pack和unpack。但是有两种调用方法,使用宏(USE_GLOBALS)来控制,第一种是使用全局接口(pack/unpack),另外一种是将这两个接口插入到string的空间里面(string.pack/string.unpack)。

lpack的具体用法 1、打包接口pack的使用,全局名字容易混淆lua本身函数unpack,使用string.pack好些,也可以修改源码修改函数名。

--luapack为我修改的接口名字
local _ss = luapack(">P", "中国asd")

local _ss2 = luapack(">h", 500)
_ss = _ss.._ss2
print(_ss, #_ss)

--调用结果
中国asd        9
中国asd       11

2、解包接口unpack的使用

--luaunpack为我修改的接口名字
--使用方式1
local ne, value = luaunpack(_ss, ">P")
print(ne, value)

_ss = string.sub(_ss, ne, #_ss)
local ne, value = luaunpack(_ss, ">h")
print(ne, value)

--调用结果
10      中国asd
3       500

--使用方式2
local ne, value1, value2 = luaunpack(_ss, ">Ph")
print(ne, value, value2)

--调用结果
12      中国asd 500

打包变量类型定义

     #define OP_ZSTRING  'z'     //空字符串
    #define OP_BSTRING  'p'     //长度小于2^8的字符串
    #define OP_WSTRING  'P'     //长度小于2^16的字符串
    #define OP_SSTRING  'a'     //长度小于2^32/64的字符串*/
    #define OP_STRING   'A'     //指定长度字符串
    #define OP_FLOAT    'f'     /* float */
    #define OP_DOUBLE   'd'     /* double */
    #define OP_NUMBER   'n'     /* Lua number */
    #define OP_CHAR     'c'     /* char */
    #define OP_BYTE     'b'     /* byte = unsigned char */
    #define OP_SHORT    'h'     /* short */
    #define OP_USHORT   'H'     /* unsigned short */
    #define OP_INT      'i'     /* int */
    #define OP_UINT     'I'     /* unsigned int */
    #define OP_LONG     'l'     /* long */
    #define OP_ULONG    'L'     /* unsigned long */

打包字节序,分为以下3种

    #define OP_LITTLEENDIAN '<'     /* little endian */
    #define OP_BIGENDIAN    '>'     /* big endian */
    #define OP_NATIVE       '='     /* native endian */
  • 好了,到这里如何使用lpack已经很清楚,接着就可以利用lpack的特性设计buff来解析网络字节流了。再次吐槽一下,这个编辑器没换缩进很难使用啊!!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏FreeBuf

Windows内核漏洞CVE-2016-0143分析

0x00 背景 4月20日,Nils Sommer在exploitdb上爆出了一枚新的Windows内核漏洞PoC。该漏洞影响所有版本的Windows操作系统,...

24060
来自专栏祝威廉

StreamingPro添加Scala script 模块支持

SQL 在解析字符串方面,能力还是有限,因为支持的算子譬如substring,split等有限,且不具备复杂的流程表达能力。我们内部有个通过JSON描述的DSL...

6930
来自专栏运维一切

ceph对象存储折腾记 原

###前言 一直想弄对象存储,以前弄过一次,不是很理解region是个什么东西,后来时间和工作上的原因没有再折腾,这两天闲了下来,再次折腾了一次。我是参考的ce...

17210
来自专栏与神兽党一起成长

解析XML和JSON内容的一点技巧

在没有统一标准的情况下,一个系统对接多个外部系统往往会遇到请求接口响应数据异构的情况,有可能返回的是XML,也有可能返回 JSON。除了返回类型不同,内容结构也...

22720
来自专栏冰霜之地

如何设计并实现一个线程安全的 Map ?(下篇)

在上篇中,我们已经讨论过如何去实现一个 Map 了,并且也讨论了诸多优化点。在下篇中,我们将继续讨论如何实现一个线程安全的 Map。说到线程安全,需要从概念开始...

54670
来自专栏Danny的专栏

System.Data.SqlClient.SqlException: 将截断字符串或二进制数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

40840
来自专栏鹅厂少年的奇妙之旅

Go内存模型

Go语言中内存分配大致有3种模式:Stack、Heap、Fixed Size Segment。

79450
来自专栏安恒网络空间安全讲武堂

从零基础到成功解题之0ctf-ezdoor

22040
来自专栏编程

JAVA面试常考系列八

题目一 JDBC是什么? JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为...

378110
来自专栏王清培的专栏

.NET/ASP.NET MVC Controller 控制器(IController控制器的创建过程)

阅读目录: 1.开篇介绍 2.ASP.NETMVC IControllerFactory 控制器工厂接口 3.ASP.NETMVC DefaultControl...

24760

扫码关注云+社区

领取腾讯云代金券