summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-11-02 00:45:02 +0800
committerruki <[email protected]>2019-11-01 22:30:18 +0800
commit4f932ba407833f9559a23037958c7388cc22d2e0 (patch)
treeb3c2b9c43b357fdba9af1f68630e733484638905
parent6d4ad7fe1c5f8ac44b420a8cb5de0bc9cd0d37b6 (diff)
improve socket.recv using bytes
-rw-r--r--core/src/xmake/io/socket_recv.c24
-rw-r--r--tests/modules/socket/tcp/file_client.lua10
-rw-r--r--xmake/core/base/bytes.lua3
-rw-r--r--xmake/core/base/socket.lua38
-rw-r--r--xmake/core/sandbox/modules/import/core/base/socket.lua8
5 files changed, 43 insertions, 40 deletions
diff --git a/core/src/xmake/io/socket_recv.c b/core/src/xmake/io/socket_recv.c
index e1f48cf9b..4ed41e080 100644
--- a/core/src/xmake/io/socket_recv.c
+++ b/core/src/xmake/io/socket_recv.c
@@ -34,7 +34,7 @@
* implementation
*/
-// real, data, errors = io.socket_recv(sock, size, prev_data)
+// real, data_or_errors = io.socket_recv(sock, size)
tb_int_t xm_io_socket_recv(lua_State* lua)
{
// check
@@ -44,7 +44,6 @@ tb_int_t xm_io_socket_recv(lua_State* lua)
if (!lua_isuserdata(lua, 1))
{
lua_pushnumber(lua, -1);
- lua_pushnil(lua);
lua_pushliteral(lua, "invalid socket!");
return 2;
}
@@ -60,37 +59,18 @@ tb_int_t xm_io_socket_recv(lua_State* lua)
if (size < 0)
{
lua_pushnumber(lua, -1);
- lua_pushnil(lua);
lua_pushfstring(lua, "invalid size(%ld)!", size);
return 2;
}
if (size > sizeof(data))
size = sizeof(data);
- // get the previous data and size first
- size_t prev_size = 0;
- tb_char_t const* prev_data = luaL_optlstring(lua, 3, "", &prev_size);
-
// recv data
tb_long_t real = tb_socket_recv(sock, data, size);
lua_pushnumber(lua, (tb_int_t)real);
if (real > 0)
{
- // init result
- luaL_Buffer result;
- luaL_buffinit(lua, &result);
-
- // prepend the previous data
- if (prev_data && prev_size) luaL_addlstring(&result, prev_data, prev_size);
- luaL_addlstring(&result, (tb_char_t const*)data, real);
-
- // save result
- luaL_pushresult(&result);
- return 2;
- }
- else if (prev_data && prev_size)
- {
- lua_pushlstring(lua, prev_data, prev_size);
+ lua_pushlstring(lua, (tb_char_t const*)data, real);
return 2;
}
return 1;
diff --git a/tests/modules/socket/tcp/file_client.lua b/tests/modules/socket/tcp/file_client.lua
index 1d2756d77..42532f5fe 100644
--- a/tests/modules/socket/tcp/file_client.lua
+++ b/tests/modules/socket/tcp/file_client.lua
@@ -10,12 +10,13 @@ function main()
local recv = 0
local data = nil
local wait = false
+ local results = {}
while true do
- real, data = sock:recv(8192, {prevdata = data})
- print(real, type(data))
+ real, data = sock:recv(8192)
if real > 0 then
recv = recv + real
wait = false
+ table.insert(results, data)
elseif real == 0 and not wait then
if sock:wait(socket.EV_RECV, -1) == socket.EV_RECV then
wait = true
@@ -26,6 +27,9 @@ function main()
break
end
end
- print("%s: recv ok, size: %d, #data: %d!", sock, recv, #data)
+ if #results > 0 then
+ data = bytes(results)
+ end
+ print("%s: recv ok, size: %d, #data: %d!", sock, recv, data and data:size() or 0)
sock:close()
end
diff --git a/xmake/core/base/bytes.lua b/xmake/core/base/bytes.lua
index 377341480..17ed435ce 100644
--- a/xmake/core/base/bytes.lua
+++ b/xmake/core/base/bytes.lua
@@ -42,6 +42,7 @@ ffi.cdef[[
-- bytes(bytes, start, last): mounts a buffer from another one, with start/last limits
-- bytes(bytes1, bytes2, bytes3, ...): allocates and concat buffer from list of byte buffers
-- bytes(bytes): allocates a buffer from another one (strict replica, sharing memory)
+-- bytes({bytes1, bytes2, ...}): allocates and concat buffer from a list of byte buffers (table)
--
function _instance.new(...)
local args = {...}
@@ -105,7 +106,7 @@ function _instance.new(...)
instance._MANAGED = true
instance._READONLY = false
elseif not arg2 and arg1[1] and type(arg1[1]) == 'table' then
- -- bytes({bytes1, bytes2, ...}) : allocates and concat buffer from a list of byte buffers (table)
+ -- bytes({bytes1, bytes2, ...}): allocates and concat buffer from a list of byte buffers (table)
args = arg1
instance._SIZE = 0
for _, b in ipairs(args) do
diff --git a/xmake/core/base/socket.lua b/xmake/core/base/socket.lua
index 6ee878bd8..26ca2b2e8 100644
--- a/xmake/core/base/socket.lua
+++ b/xmake/core/base/socket.lua
@@ -24,6 +24,7 @@ local _instance = _instance or {}
-- load modules
local io = require("base/io")
+local bytes = require("base/bytes")
local table = require("base/table")
local string = require("base/string")
@@ -193,7 +194,8 @@ function _instance:send(data, opt)
local wait = false
local errors = nil
if opt.block then
- while start < last do
+ local size = last + 1 - start
+ while start <= last do
real, errors = io.socket_send(self._SOCK, data, start, last)
if real > 0 then
send = send + real
@@ -211,6 +213,9 @@ function _instance:send(data, opt)
break
end
end
+ if send ~= size then
+ send = -1
+ end
else
send, errors = io.socket_send(self._SOCK, data, start, last)
if send < 0 and errors then
@@ -251,7 +256,8 @@ function _instance:sendfile(file, opt)
local wait = false
local errors = nil
if opt.block then
- while start < last do
+ local size = last + 1 - start
+ while start <= last do
real, errors = io.socket_sendfile(self._SOCK, file._FILE, start, last)
if real > 0 then
send = send + real
@@ -269,6 +275,9 @@ function _instance:sendfile(file, opt)
break
end
end
+ if send ~= size then
+ send = -1
+ end
else
send, errors = io.socket_sendfile(self._SOCK, file._FILE, start, last)
if send < 0 and errors then
@@ -299,33 +308,42 @@ function _instance:recv(size, opt)
local recv = 0
local real = 0
local wait = false
- local data = opt.prevdata
- local errors = nil
+ local data_or_errors = nil
if opt.block then
+ local results = {}
while recv < size do
- real, data, errors = io.socket_recv(self._SOCK, size - recv, data)
+ real, data_or_errors = io.socket_recv(self._SOCK, size - recv)
if real > 0 then
recv = recv + real
wait = false
+ table.insert(results, bytes(data_or_errors))
elseif real == 0 and not wait then
local events, waiterrs = self:wait(socket.EV_RECV, opt.timeout or -1)
if events == socket.EV_RECV then
wait = true
else
- errors = waiterrs
+ data_or_errors = waiterrs
break
end
else
break
end
end
+ if recv == size then
+ data_or_errors = bytes(results)
+ else
+ recv = -1
+ end
else
- recv, data, errors = io.socket_recv(self._SOCK, size, data)
+ recv, data_or_errors = io.socket_recv(self._SOCK, size)
+ if recv > 0 then
+ data_or_errors = bytes(data_or_errors)
+ end
end
- if recv < 0 and errors then
- errors = string.format("%s: %s", self, errors)
+ if recv < 0 and data_or_errors then
+ data_or_errors = string.format("%s: %s", self, data_or_errors)
end
- return recv, data, errors
+ return recv, data_or_errors
end
-- wait socket events
diff --git a/xmake/core/sandbox/modules/import/core/base/socket.lua b/xmake/core/sandbox/modules/import/core/base/socket.lua
index e6a0b88cd..3d679bd52 100644
--- a/xmake/core/sandbox/modules/import/core/base/socket.lua
+++ b/xmake/core/sandbox/modules/import/core/base/socket.lua
@@ -125,11 +125,11 @@ end
-- recv data from socket
function sandbox_core_base_socket_instance.recv(sock, size, opt)
- local real, data, errors = sock:_recv(size, opt)
- if real < 0 and errors then
- raise(errors)
+ local real, data_or_errors = sock:_recv(size, opt)
+ if real < 0 and data_or_errors then
+ raise(data_or_errors)
end
- return real, data
+ return real, data_or_errors
end
-- get socket rawfd