- 最近在研究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好些,也可以修改源碼修改函數名。1 --luapack為我修改的接口名字 2 local _ss = luapack(">P", "中國asd") 3 4 local _ss2 = luapack(">h", 500) 5 _ss = _ss.._ss2 6 print(_ss, #_ss) 7 8 --調用結果 9 中國asd 9 10 中國asd 11
-
2、解包接口unpack的使用
1 --luaunpack為我修改的接口名字 2 --使用方式1 3 local ne, value = luaunpack(_ss, ">P") 4 print(ne, value) 5 6 _ss = string.sub(_ss, ne, #_ss) 7 local ne, value = luaunpack(_ss, ">h") 8 print(ne, value) 9 10 --調用結果 11 10 中國asd 12 3 500 13 14 --使用方式2 15 local ne, value1, value2 = luaunpack(_ss, ">Ph") 16 print(ne, value, value2) 17 18 --調用結果 19 12 中國asd 500
-
打包變量類型定義
-
1 #define OP_ZSTRING 'z' //空字符串 2 #define OP_BSTRING 'p' //長度小於2^8的字符串 3 #define OP_WSTRING 'P' //長度小於2^16的字符串 4 #define OP_SSTRING 'a' //長度小於2^32/64的字符串*/ 5 #define OP_STRING 'A' //指定長度字符串 6 #define OP_FLOAT 'f' /* float */ 7 #define OP_DOUBLE 'd' /* double */ 8 #define OP_NUMBER 'n' /* Lua number */ 9 #define OP_CHAR 'c' /* char */ 10 #define OP_BYTE 'b' /* byte = unsigned char */ 11 #define OP_SHORT 'h' /* short */ 12 #define OP_USHORT 'H' /* unsigned short */ 13 #define OP_INT 'i' /* int */ 14 #define OP_UINT 'I' /* unsigned int */ 15 #define OP_LONG 'l' /* long */ 16 #define OP_ULONG 'L' /* unsigned long */
- 打包字節序,分為以下3種
-
1 #define OP_LITTLEENDIAN '<' /* little endian */ 2 #define OP_BIGENDIAN '>' /* big endian */ 3 #define OP_NATIVE '=' /* native endian */
-
好了,到這里如何使用lpack已經很清楚,接着就可以利用lpack的特性設計buff來解析網絡字節流了。
- 也可以使用包管理來進行直接安裝:詳見 socket使用安裝篇
微信搜索【水勺子】關注我,獲取更多詳細信息