diff options
| author | ruki <[email protected]> | 2019-11-02 00:45:02 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2019-11-01 22:30:18 +0800 |
| commit | 4f932ba407833f9559a23037958c7388cc22d2e0 (patch) | |
| tree | b3c2b9c43b357fdba9af1f68630e733484638905 | |
| parent | 6d4ad7fe1c5f8ac44b420a8cb5de0bc9cd0d37b6 (diff) | |
improve socket.recv using bytes
| -rw-r--r-- | core/src/xmake/io/socket_recv.c | 24 | ||||
| -rw-r--r-- | tests/modules/socket/tcp/file_client.lua | 10 | ||||
| -rw-r--r-- | xmake/core/base/bytes.lua | 3 | ||||
| -rw-r--r-- | xmake/core/base/socket.lua | 38 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/base/socket.lua | 8 |
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 |
