Some additions and fixes.

Added new functions: select, set(non)blocking, isBlocking.
Set default to non-blocking. Added "would block" to ignored errors.
develop
Warmist 2015-09-16 09:57:22 +03:00
parent b58ccc9e55
commit 80fd4b1365
2 changed files with 78 additions and 18 deletions

@ -20,18 +20,37 @@ function socket:close( )
_funcs.lua_client_close(self.server_id,self.client_id)
end
end
function socket:isBlocking()
return _funcs.lua_socket_is_blocking(self.server_id,self.client_id)
end
function socket:setBlocking()
_funcs.lua_socket_set_blocking(self.server_id,self.client_id,true)
end
function socket:setNonblocking()
_funcs.lua_socket_set_blocking(self.server_id,self.client_id,false)
end
function socket:setTimeout( sec,msec )
msec=msec or 0
_funcs.lua_socket_set_timeout(self.server_id,self.client_id,sec,msec)
self.timeout={s=sec,ms=msec}
end
function socket:select(sec,msec)
if sec == nil and msec==nil then
local timeout=self.timeout or {s=0,ms=0}
sec=timeout.s
msec=timeout.ms
end
return _funcs.lua_socket_select(self.server_id,self.client_id,sec,msec)
end
local client=defclass(client,socket)
function client:receive( pattern )
local pattern=pattern or "*l"
local bytes=-1
if type(pattern)== number then
bytes=pattern
end
local ret=_funcs.lua_client_receive(self.server_id,self.client_id,bytes,pattern,false)
if ret=="" then
return

@ -108,9 +108,11 @@ std::pair<CActiveSocket*,clients_map*> get_client(int server_id,int client_id)
}
void handle_error(CSimpleSocket::CSocketError err,bool skip_timeout=true)
{
if(err==CSimpleSocket::SocketSuccess)
if (err == CSimpleSocket::SocketSuccess)
return;
if(err==CSimpleSocket::SocketTimedout && skip_timeout)
if (err == CSimpleSocket::SocketTimedout && skip_timeout)
return;
if (err == CSimpleSocket::SocketEwouldblock && skip_timeout)
return;
throw std::runtime_error(translate_socket_error(err));
}
@ -218,6 +220,7 @@ static std::string lua_client_receive(int server_id,int client_id,int bytes,std:
break;
}
ret+=(char)*sock->GetData();
}
return ret;
}
@ -285,42 +288,80 @@ static int lua_socket_connect(std::string ip,int port)
delete sock;
throw std::runtime_error(translate_socket_error(err));
}
sock->SetNonblocking();
last_client_id++;
clients[last_client_id]=sock;
return last_client_id;
}
static void lua_socket_set_timeout(int server_id,int client_id,int32_t sec,int32_t msec)
CSimpleSocket* get_socket(int server_id, int client_id)
{
std::map<int,CActiveSocket*>* target=&clients;
if(server_id>0)
std::map<int, CActiveSocket*>* target = &clients;
if (server_id>0)
{
if(servers.count(server_id)==0)
if (servers.count(server_id) == 0)
{
throw std::runtime_error("Server with this id does not exist");
}
server &cur_server=servers[server_id];
if(client_id==-1)
server &cur_server = servers[server_id];
if (client_id == -1)
{
cur_server.socket->SetConnectTimeout(sec,msec);
cur_server.socket->SetReceiveTimeout(sec,msec);
cur_server.socket->SetSendTimeout(sec,msec);
return;
return cur_server.socket;
}
target=&cur_server.clients;
target = &cur_server.clients;
}
if(target->count(client_id)==0)
if (target->count(client_id) == 0)
{
throw std::runtime_error("Client does with this id not exist");
}
CActiveSocket *sock=(*target)[client_id];
CActiveSocket *sock = (*target)[client_id];
return sock;
}
static void lua_socket_set_timeout(int server_id,int client_id,int32_t sec,int32_t msec)
{
CSimpleSocket *sock = get_socket(server_id, client_id);
sock->SetConnectTimeout(sec,msec);
sock->SetReceiveTimeout(sec,msec);
sock->SetSendTimeout(sec,msec);
if (!sock->SetReceiveTimeout(sec, msec) ||
!sock->SetSendTimeout(sec, msec))
{
CSimpleSocket::CSocketError err = sock->GetSocketError();
throw std::runtime_error(translate_socket_error(err));
}
}
static bool lua_socket_select(int server_id, int client_id, int32_t sec, int32_t msec)
{
CSimpleSocket *sock = get_socket(server_id, client_id);
return sock->Select(sec, msec);
}
static void lua_socket_set_blocking(int server_id, int client_id, bool value)
{
CSimpleSocket *sock = get_socket(server_id, client_id);
bool ok;
if (value)
{
ok = sock->SetBlocking();
}
else
{
ok = sock->SetNonblocking();
}
if (!ok)
{
CSimpleSocket::CSocketError err = sock->GetSocketError();
throw std::runtime_error(translate_socket_error(err));
}
}
static bool lua_socket_is_blocking(int server_id, int client_id)
{
CSimpleSocket *sock = get_socket(server_id, client_id);
return !sock->IsNonblocking();
}
DFHACK_PLUGIN_LUA_FUNCTIONS {
DFHACK_LUA_FUNCTION(lua_socket_bind), //spawn a server
DFHACK_LUA_FUNCTION(lua_socket_connect),//spawn a client (i.e. connection)
DFHACK_LUA_FUNCTION(lua_socket_select),
DFHACK_LUA_FUNCTION(lua_socket_set_blocking),
DFHACK_LUA_FUNCTION(lua_socket_is_blocking),
DFHACK_LUA_FUNCTION(lua_socket_set_timeout),
DFHACK_LUA_FUNCTION(lua_server_accept),
DFHACK_LUA_FUNCTION(lua_server_close),