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) _funcs.lua_client_close(self.server_id,self.client_id)
end end
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 ) function socket:setTimeout( sec,msec )
msec=msec or 0 msec=msec or 0
_funcs.lua_socket_set_timeout(self.server_id,self.client_id,sec,msec) _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 end
local client=defclass(client,socket) local client=defclass(client,socket)
function client:receive( pattern ) function client:receive( pattern )
local pattern=pattern or "*l" local pattern=pattern or "*l"
local bytes=-1 local bytes=-1
if type(pattern)== number then if type(pattern)== number then
bytes=pattern bytes=pattern
end end
local ret=_funcs.lua_client_receive(self.server_id,self.client_id,bytes,pattern,false) local ret=_funcs.lua_client_receive(self.server_id,self.client_id,bytes,pattern,false)
if ret=="" then if ret=="" then
return 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) void handle_error(CSimpleSocket::CSocketError err,bool skip_timeout=true)
{ {
if(err==CSimpleSocket::SocketSuccess) if (err == CSimpleSocket::SocketSuccess)
return; return;
if(err==CSimpleSocket::SocketTimedout && skip_timeout) if (err == CSimpleSocket::SocketTimedout && skip_timeout)
return;
if (err == CSimpleSocket::SocketEwouldblock && skip_timeout)
return; return;
throw std::runtime_error(translate_socket_error(err)); 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; break;
} }
ret+=(char)*sock->GetData(); ret+=(char)*sock->GetData();
} }
return ret; return ret;
} }
@ -285,42 +288,80 @@ static int lua_socket_connect(std::string ip,int port)
delete sock; delete sock;
throw std::runtime_error(translate_socket_error(err)); throw std::runtime_error(translate_socket_error(err));
} }
sock->SetNonblocking();
last_client_id++; last_client_id++;
clients[last_client_id]=sock; clients[last_client_id]=sock;
return last_client_id; 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; std::map<int, CActiveSocket*>* target = &clients;
if(server_id>0) 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"); throw std::runtime_error("Server with this id does not exist");
} }
server &cur_server=servers[server_id]; server &cur_server = servers[server_id];
if(client_id==-1) if (client_id == -1)
{ {
cur_server.socket->SetConnectTimeout(sec,msec); return cur_server.socket;
cur_server.socket->SetReceiveTimeout(sec,msec);
cur_server.socket->SetSendTimeout(sec,msec);
return;
} }
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"); 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->SetConnectTimeout(sec,msec);
sock->SetReceiveTimeout(sec,msec); if (!sock->SetReceiveTimeout(sec, msec) ||
sock->SetSendTimeout(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_PLUGIN_LUA_FUNCTIONS {
DFHACK_LUA_FUNCTION(lua_socket_bind), //spawn a server 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_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_socket_set_timeout),
DFHACK_LUA_FUNCTION(lua_server_accept), DFHACK_LUA_FUNCTION(lua_server_accept),
DFHACK_LUA_FUNCTION(lua_server_close), DFHACK_LUA_FUNCTION(lua_server_close),