LuaSocket 简介:
LuaSocket is a Lua extension library that is composed by two parts:
a C core that provides support for the TCP and UDP transport layers, and a set of Lua modules that add support for functionality commonly needed by applications that deal with the Internet.
the core support has been implemented so that it is both efficient and simple to use. It is available to any Lua application once it has been properly initialized by the interpreter in use.
The code has been tested and runs well on several Windows and Unix platforms.
LuaSocket version 2.0.2 is now available for download! It is compatible with Lua 5.1, and has been tested on Windows XP, Linux, and Mac OS X.
2.0.2 is just a bug-fix/update release.
LuaSocket 是一个Lua的拓展库。包括两个部分:C语言编写提供Tcp和Udp 传输层协议的核心模块和支持处理网络Lua模块。
核心模块被高效且简单的是实现。仅仅要嵌入lua解释器就可以使用。核心模块已经在多个windows和unix 操作系统测试和运行。
LuaSocket 2.0.2版本和Lua 5.1.x版本兼容,已经在window xp ,linux 和 Mac os X操作系统测试过。
LuaSocket 作为一个bug 修复版本释放。
LuaSocket 使用:
本文使用windows 7 操作系统和使用vs2010 工具。所以仅仅测试winsock api 部分。
1,在导入头文件和源文件时,移除usocket等相关unix操行系统下的文件。
2 在wsocket.h 中加入 #pragma comment(lib,"ws2_32.lib") 导入 winsock库,否则在link过程中,会找到socket api相关函数。
luasocketsample.cpp 文件内容如下:
extern "C" { #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include "luasocket.h" //使用LuaSocket 库仅仅需要包含的头文件。 } int main(int argc, char **argv) { //创建lua_State lua_State *L = lua_open(); /* create state */ //注册标准库 luaL_openlibs (L); //注册LuaSocket库 luaopen_socket_core(L); //执行sample_1.lua luaL_dofile (L, "luasocketsample.lua"); //关闭lua_State lua_close(L); return 1; }
在LuaSocket 源代码中有例子,以下例子取自echosrvr.lua 文件并部分修改:
local host = host or "127.0.0.1" local port = port or 8080 print("Binding to host '" ..host.. "' and port " ..port.. "...") --创建udp对象 udp = assert(socket.udp()) --绑定到指定的端口 assert(udp:setsockname(host, port)) --设置超时时间 assert(udp:settimeout(5)) --获取绑定IP和端口 ip, port = udp:getsockname() assert(ip, port) print("Waiting packets on " .. ip .. ":" .. port .. "...") local recvmaxbyte =20 --单线程无限循环 while 1 do --接收udp packet dgram, ip, port = udp:receivefrom(recvmaxbyte) if(dgram=="终止")then print("终止") break end if dgram then print("Echoing '" .. dgram .. "' to " .. ip .. ":" .. port) --发送数据 udp:sendto(dgram, ip, port) else print(ip) end end udp=nil collectgarbage("collect")
运行结果如下:
luasocket文件为使用LuaSokct 需要包含的文件,代码非常简单。
/*=========================================================================** LuaSocket toolkit * Networking support for the Lua language * Diego Nehab * 26/11/1999 * * This library is part of an effort to progressively increase the network * connectivity of the Lua language. The Lua interface to networking * functions follows the Sockets API closely, trying to simplify all tasks * involved in setting up both client and server connections. The provided * IO routines, however, follow the Lua style, being very similar to the * standard Lua read and write functions. * * RCS ID: $Id: luasocket.c,v 1.53 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ /*=========================================================================** Standard include files \*=========================================================================*/ #include "lua.h" #include "lauxlib.h" #if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) #include "compat-5.1.h" #endif /*=========================================================================** LuaSocket includes \*=========================================================================*/ #include "luasocket.h" #include "auxiliar.h" #include "except.h" #include "timeout.h" #include "buffer.h" #include "inet.h" #include "tcp.h" #include "udp.h" #include "select.h" /*-------------------------------------------------------------------------** Internal function prototypes \*-------------------------------------------------------------------------*/ static int global_skip(lua_State *L); static int global_unload(lua_State *L); static int base_open(lua_State *L); /*-------------------------------------------------------------------------** Modules and functions \*-------------------------------------------------------------------------*/ //这是LuaSocket 提供的所有Lua 模块功能 static const luaL_reg mod[] = { {"auxiliar", auxiliar_open}, {"except", except_open}, {"timeout", timeout_open}, {"buffer", buffer_open}, {"inet", inet_open}, {"tcp", tcp_open}, {"udp", udp_open}, {"select", select_open}, {NULL, NULL} }; static luaL_reg func[] = { {"skip", global_skip}, {"__unload", global_unload}, {NULL, NULL} }; /*-------------------------------------------------------------------------** Skip a few arguments \*-------------------------------------------------------------------------*/ static int global_skip(lua_State *L) { int amount = luaL_checkint(L, 1); int ret = lua_gettop(L) - amount - 1; return ret >= 0 ? ret : 0; } /*-------------------------------------------------------------------------** Unloads the library \*-------------------------------------------------------------------------*/ static int global_unload(lua_State *L) { (void) L; socket_close(); return 0; } /*-------------------------------------------------------------------------** Setup basic stuff. \*-------------------------------------------------------------------------*/ static int base_open(lua_State *L) { //通过判断不同操作系统提供的socket 基础,在window操作系统是使用winsock2.0版本 if (socket_open()) { /* export functions (and leave namespace table on top of stack) */ //注册LuaSocket到_G["socket"] luaL_openlib(L, "socket", func, 0); #ifdef LUASOCKET_DEBUG lua_pushstring(L, "_DEBUG"); lua_pushboolean(L, 1); lua_rawset(L, -3); #endif /* make version string available to scripts */ lua_pushstring(L, "_VERSION"); lua_pushstring(L, LUASOCKET_VERSION); lua_rawset(L, -3); return 1; } else { lua_pushstring(L, "unable to initialize library"); lua_error(L); return 0; } } /*-------------------------------------------------------------------------** Initializes all library modules. \*-------------------------------------------------------------------------*/ //使用LuaSocket ,luaopen_socket_core()函数来注册所有相关模块. LUASOCKET_API int luaopen_socket_core(lua_State *L) { int i; base_open(L); for (i = 0; mod[i].name; i++) mod[i].func(L); return 1; }
小结:
LuaSocket 作为Lua的网络拓展库,使用LuaSocket 可以跨平台。可以在window ,unix 以及mac 操作系统下面使用。window 平台下面,LuaSocket 仅仅使用14个头文件。
源代码行数在大于1000行到2000行之间。库小,很容易理解学习。在window 操作系统下面,仅仅使用了select IO模型。像Java Nio 底层也是封装了window操行系统的select
IO模型。在学习过程中,可以使用最小的理解成本来学习如果封装一个socket网络库。这一点很赞。还有LuaSocket 库提供的功能小巧实用,没有多余代码。Socket 核心部分通过wsocket和usocket 来提供,udp 和tcp 协议通过单独文件来实现。我希望通过对LuaSocket 库学习来更好理解 学习 封装自己的网络库。
同时,LuaSocket 提供面向对象编程方法,这样我们还可以继续复习之前Lua和C语言交互部分。如果对Lua和C语言交互部分不能深刻理解,在学习LuaSocket 部分会有不少阻碍。
版权声明:本文为博主原创文章,未经博主允许不得转载。