mirror of
https://github.com/ctruLua/ctruLua.git
synced 2025-10-27 16:39:29 +00:00
Added documentation and (untested) code for server sockets
This commit is contained in:
parent
8500bcb8fa
commit
4d56037289
1 changed files with 111 additions and 18 deletions
129
source/socket.c
129
source/socket.c
|
|
@ -1,7 +1,5 @@
|
|||
/***
|
||||
The `socket` module. Almost like luasocket, but for TCP/UDP only.
|
||||
See http://w3.impa.br/~diego/software/luasocket/reference.html for a
|
||||
documentation.
|
||||
The `socket` module. Almost like luasocket, but for TCP only.
|
||||
@module ctr.socket
|
||||
@usage local socket = require("ctr.socket")
|
||||
*/
|
||||
|
|
@ -29,8 +27,13 @@ typedef struct {
|
|||
struct hostent *host; // only user for client sockets
|
||||
} socket_userdata;
|
||||
|
||||
/***
|
||||
Initialize the socket module
|
||||
@function init
|
||||
@tparam[opt=0x100000] number buffer size (in bytes), must be a multiple of 0x1000
|
||||
*/
|
||||
static int socket_init(lua_State *L) {
|
||||
u32 size = luaL_optinteger(L, 1, 0x10000);
|
||||
u32 size = luaL_optinteger(L, 1, 0x100000);
|
||||
Result ret = SOC_Initialize((u32*)memalign(0x1000, size), size);
|
||||
|
||||
if (ret) {
|
||||
|
|
@ -43,55 +46,116 @@ static int socket_init(lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
Disable the socket module. Must be called before exiting ctrµLua.
|
||||
@function shutdown
|
||||
*/
|
||||
static int socket_shutdown(lua_State *L) {
|
||||
SOC_Shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
Return a TCP socket.
|
||||
@function tcp
|
||||
@treturn TCPMaster TCP socket
|
||||
*/
|
||||
static int socket_tcp(lua_State *L) {
|
||||
socket_userdata *data = lua_newuserdata(L, sizeof(*data));
|
||||
socket_userdata *userdata = lua_newuserdata(L, sizeof(*userdata));
|
||||
luaL_getmetatable(L, "LSocket");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
data->socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (data->socket < 0) {
|
||||
userdata->socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (userdata->socket < 0) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "Failed to create a TCP socket");
|
||||
return 2;
|
||||
}
|
||||
|
||||
data->addr.sin_family = AF_INET;
|
||||
userdata->addr.sin_family = AF_INET;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* methods */
|
||||
/***
|
||||
TCP Sockets
|
||||
@section TCP
|
||||
*/
|
||||
|
||||
static int socket_close(lua_State *L) {
|
||||
socket_userdata *data = luaL_checkudata(L, 1, "LSocket");
|
||||
/***
|
||||
Accept a connection on a server.
|
||||
@function :accept
|
||||
@treturn TCPClient tcp client object, or nil.
|
||||
*/
|
||||
static int socket_accept(lua_State *L) {
|
||||
socket_userdata *userdata = luaL_checkudata(L, 1, "LSocket");
|
||||
|
||||
close(data->socket);
|
||||
socket_userdata *client = lua_newuserdata(L, sizeof(*client));
|
||||
luaL_getmetatable(L, "LSocket");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
socklen_t addrSize = sizeof(client->addr);
|
||||
client->socket = accept(userdata->socket, (struct sockaddr*)&client->addr, &addrSize);
|
||||
if (client->socket < 0) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
Bind a socket. The TCP object become a TCPServer object.
|
||||
@function :bind
|
||||
@tparam number port the port to bind the socket on.
|
||||
*/
|
||||
static int socket_bind(lua_State *L) {
|
||||
socket_userdata *userdata = luaL_checkudata(L, 1, "LSocket");
|
||||
int port = luaL_checkinteger(L, 2);
|
||||
|
||||
userdata->addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
userdata->addr.sin_port = htons(port);
|
||||
|
||||
bind(userdata->socket, (struct sockaddr*)&userdata->addr, sizeof(userdata->addr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
Close an existing socket.
|
||||
@function :close
|
||||
*/
|
||||
static int socket_close(lua_State *L) {
|
||||
socket_userdata *userdata = luaL_checkudata(L, 1, "LSocket");
|
||||
|
||||
closesocket(userdata->socket);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
Connect a socket to a server. The TCP object becomes a TCPClient object.
|
||||
@function :connect
|
||||
@tparam string host address of the host
|
||||
@tparam number port port of the server
|
||||
*/
|
||||
static int socket_connect(lua_State *L) {
|
||||
socket_userdata *data = luaL_checkudata(L, 1, "LSocket");
|
||||
socket_userdata *userdata = luaL_checkudata(L, 1, "LSocket");
|
||||
char *addr = (char*)luaL_checkstring(L, 2);
|
||||
int port = luaL_checkinteger(L, 3);
|
||||
|
||||
data->host = gethostbyname(addr);
|
||||
if (data->host == NULL) {
|
||||
userdata->host = gethostbyname(addr);
|
||||
if (userdata->host == NULL) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "No such host");
|
||||
return 2;
|
||||
}
|
||||
|
||||
data->addr.sin_port = htons(port);
|
||||
bcopy((char*)data->host->h_addr, (char*)&data->addr.sin_addr.s_addr, data->host->h_length);
|
||||
userdata->addr.sin_port = htons(port);
|
||||
bcopy((char*)userdata->host->h_addr, (char*)&userdata->addr.sin_addr.s_addr, userdata->host->h_length);
|
||||
|
||||
if (connect(data->socket, (const struct sockaddr*)&data->addr, sizeof(data->addr)) < 0) {
|
||||
if (connect(userdata->socket, (const struct sockaddr*)&userdata->addr, sizeof(userdata->addr)) < 0) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "Connection failed");
|
||||
return 2;
|
||||
|
|
@ -101,6 +165,26 @@ static int socket_connect(lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
Open the socket for connections.
|
||||
@function :listen
|
||||
@tparam[opt=16] number max maximum number of simultaneous connections
|
||||
*/
|
||||
static int socket_listen(lua_State *L) {
|
||||
socket_userdata *userdata = luaL_checkudata(L, 1, "LSocket");
|
||||
int max = luaL_optinteger(L, 2, 16);
|
||||
|
||||
listen(userdata->socket, max);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
Receive some data from the socket.
|
||||
@function :receive
|
||||
@tparam number size amount of data to receive; can also be "*a" to receive everything
|
||||
@treturn string data
|
||||
*/
|
||||
static int socket_receive(lua_State *L) {
|
||||
socket_userdata *userdata = luaL_checkudata(L, 1, "LSocket");
|
||||
int count = 0;
|
||||
|
|
@ -122,6 +206,12 @@ static int socket_receive(lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
Send some data over the TCP socket.
|
||||
@function :send
|
||||
@tparam string data data to send
|
||||
@treturn number amount of data sent
|
||||
*/
|
||||
static int socket_send(lua_State *L) {
|
||||
socket_userdata *userdata = luaL_checkudata(L, 1, "LSocket");
|
||||
size_t size = 0;
|
||||
|
|
@ -143,8 +233,11 @@ static const struct luaL_Reg socket_functions[] = {
|
|||
|
||||
// object
|
||||
static const struct luaL_Reg socket_methods[] = {
|
||||
{"accept", socket_accept },
|
||||
{"bind", socket_bind },
|
||||
{"close", socket_close },
|
||||
{"connect", socket_connect },
|
||||
{"listen", socket_listen },
|
||||
{"receive", socket_receive },
|
||||
{"send", socket_send },
|
||||
{NULL, NULL}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue