mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 04:28:20 +01:00
Add. acceptfd method.
socket.tcp can accept fd and socket type ('master'(default), 'client') acceptfd method can be used to write multi-threaded server. ```lua -- main thread local fd = srv_sock:acceptfd() Threads.runfile('echo.lua', fd) -- echo.lua local fd = ... local sock = socket.tcp(fd,'client') ``` or to interact with library such as [ESL](http://wiki.freeswitch.org/wiki/Event_Socket_Library) ```lua local fd = srv_sock:acceptfd() Threads.runfile('worker.lua', fd) -- worker.lua local sock = ESLconnection((...)) ``` If we need just close fd (for example we can not run worker thread) we should call `socket.tcp(fd,'client'):close()`
This commit is contained in:
parent
5341131cd0
commit
addee9d8fb
39
src/tcp.c
39
src/tcp.c
@ -3,6 +3,7 @@
|
||||
* LuaSocket toolkit
|
||||
\*=========================================================================*/
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
@ -31,6 +32,7 @@ static int meth_getpeername(lua_State *L);
|
||||
static int meth_shutdown(lua_State *L);
|
||||
static int meth_receive(lua_State *L);
|
||||
static int meth_accept(lua_State *L);
|
||||
static int meth_acceptfd(lua_State *L);
|
||||
static int meth_close(lua_State *L);
|
||||
static int meth_getoption(lua_State *L);
|
||||
static int meth_setoption(lua_State *L);
|
||||
@ -44,6 +46,7 @@ static luaL_Reg tcp_methods[] = {
|
||||
{"__gc", meth_close},
|
||||
{"__tostring", auxiliar_tostring},
|
||||
{"accept", meth_accept},
|
||||
{"acceptfd", meth_acceptfd},
|
||||
{"bind", meth_bind},
|
||||
{"close", meth_close},
|
||||
{"connect", meth_connect},
|
||||
@ -213,6 +216,28 @@ static int meth_accept(lua_State *L)
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Waits for and returns a client object attempting connection to the
|
||||
* server object
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int meth_acceptfd(lua_State *L)
|
||||
{
|
||||
p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1);
|
||||
p_timeout tm = timeout_markstart(&server->tm);
|
||||
t_socket sock;
|
||||
const char *err = inet_tryaccept(&server->sock, server->family, &sock, tm);
|
||||
/* if successful, push client socket */
|
||||
if (err == NULL) {
|
||||
lua_pushnumber(L, sock);
|
||||
assert((t_socket)lua_tonumber(L, -1) == sock); // do we need check at runtime?
|
||||
return 1;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, err);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Binds an object to an address
|
||||
\*-------------------------------------------------------------------------*/
|
||||
@ -356,14 +381,24 @@ static int meth_settimeout(lua_State *L)
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int tcp_create(lua_State *L, int family) {
|
||||
t_socket sock;
|
||||
const char *err = inet_trycreate(&sock, family, SOCK_STREAM);
|
||||
const char *err;
|
||||
const int is_inherite = lua_isnumber(L,1);
|
||||
const char *obj_type = "tcp{master}";
|
||||
if (is_inherite){
|
||||
err = NULL;
|
||||
sock = (t_socket)lua_tonumber(L, 1);
|
||||
if(strstr(luaL_optstring(L,2,""),"client"))
|
||||
obj_type = "tcp{client}";
|
||||
}
|
||||
else
|
||||
err = inet_trycreate(&sock, family, SOCK_STREAM);
|
||||
/* try to allocate a system socket */
|
||||
if (!err) {
|
||||
/* allocate tcp object */
|
||||
p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
|
||||
memset(tcp, 0, sizeof(t_tcp));
|
||||
/* set its type as master object */
|
||||
auxiliar_setclass(L, "tcp{master}", -1);
|
||||
auxiliar_setclass(L, obj_type, -1);
|
||||
/* initialize remaining structure fields */
|
||||
socket_setnonblocking(&sock);
|
||||
if (family == PF_INET6) {
|
||||
|
22
test/test_acceptfd.lua
Normal file
22
test/test_acceptfd.lua
Normal file
@ -0,0 +1,22 @@
|
||||
local socket = require "socket"
|
||||
|
||||
local host, port = "127.0.0.1", "5462"
|
||||
|
||||
local srv = assert(socket.bind(host, port))
|
||||
|
||||
local sock = socket.tcp()
|
||||
assert(sock:connect(host, port))
|
||||
|
||||
local fd = assert(srv:acceptfd())
|
||||
assert(type(fd) == "number")
|
||||
|
||||
local cli = assert(socket.tcp(fd, "client"))
|
||||
|
||||
assert(5 == assert(cli:send("hello")))
|
||||
assert("hello" == assert(sock:receive(5)))
|
||||
|
||||
cli:close()
|
||||
sock:close()
|
||||
srv:close()
|
||||
|
||||
print("done!")
|
Loading…
Reference in New Issue
Block a user