![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 int 2 luaopen_netpack(lua_State *L) { 3 luaL_checkversion(L); 4 luaL_Reg l[] = { 5 { "pop", lpop },//从队列头弹出一个netpack,netpack没有被释放 6 { "pack", lpack },//将string打包成2个字节长度+内容 7 { "clear", lclear },//释放queue 8 { "tostring", ltostring },//将userdata转成string 9 { NULL, NULL }, 10 }; 11 luaL_newlib(L,l); 12 13 // the order is same with macros : TYPE_* (defined top) 14 lua_pushliteral(L, "data");//将对应的标签放进栈 15 lua_pushliteral(L, "more"); 16 lua_pushliteral(L, "error"); 17 lua_pushliteral(L, "open"); 18 lua_pushliteral(L, "close"); 19 lua_pushliteral(L, "warning"); 20 21 lua_pushcclosure(L, lfilter, 6); 22 lua_setfield(L, -2, "filter");//根据buf的type,解析参数 23 24 return 1; 25 }
netpack中的定义的结构体
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 struct netpack { 2 int id; 3 int size; 4 void * buffer; 5 }; 6 7 struct uncomplete { 8 struct netpack pack; 9 struct uncomplete * next; 10 int read; 11 int header; 12 }; 13 14 struct queue { 15 int cap;//capacity队列容量 16 int head; 17 int tail; 18 struct uncomplete * hash[HASHSIZE]; 19 struct netpack queue[QUEUESIZE]; 20 };
netpack.filter函数主要在gateserver中用于过滤socket类型的消息,然后按照信息类型,返回不同的参数给lua
层调用,在lua中调用过程如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 skynet.register_protocol { 2 name = "socket", 3 id = skynet.PTYPE_SOCKET, -- PTYPE_SOCKET = 6 4 unpack = function ( msg, sz ) 5 return netpack.filter( queue, msg, sz) 6 end, 7 dispatch = function (_, _, q, type, ...) 8 queue = q 9 if type then 10 MSG[type](...) 11 end 12 end 13 }
netpack.pack函数主要将一个字符串打包成2个字节的长度+字符串,然后返回到lua层,这个功能类似于string.pack(">s2", str),这个功能有可能是lua5.1版本的skynet遗留下来的功能。
netpack.pop函数主要是通过弹出队列中的头元素,在gateserver.lua接收到data类型的消息时,会将接收到的buffer加到queue中,当pop的时候,然后返回queue中头成员的netpack结构体中的成员变量。
netpack.clear函数,主要释放queue中的所有内存
netpack.tostring函数,通过lua层传入userdata对象,强制转换为string类型返回给lua层
转载请注明出处,from 博客园HemJohn