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);
  1. 将lpack编译成dll(so),然后在lua里面调用:
require("lpack")

然后说一下lpack的接口,lpack扩展库提供了两个接口,packunpack。但是有两种调用方法,使用宏(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
  1. 解包接口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 */

项目举例

function parcel_method:read_ussd_buff()
    local buf = string.sub(self.buffer, self.pos,#self.buffer)
    local pos,hex_value
    local str_buffer = ""
    for index =1,#buf,2 do
        pos, hex_value = string.unpack(buf,"<h")
        -- log.debug("ussd hex_value=%d",hex_value)
        if hex_value > 0 and hex_value < 128 then  --入参必须是ASCII码
            local str_chr = string.char(hex_value)
            str_buffer = str_buffer .. str_chr
        end
        buf = string.sub(buf,pos)
        -- print(string.unpack(str,">h"))
    end

    self.pos = self.pos + pos - 1

    -- log.debug("ussd " .. str_buffer)
    return str_buffer
end

好了,到这里如何使用lpack已经很清楚,接着就可以利用lpack的特性设计buff来解析网络字节流了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值