diff options
| author | ruki <[email protected]> | 2019-10-27 21:08:19 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2019-10-27 21:08:19 +0800 |
| commit | 239d4dead77af769ba5adccb58f30e9d52238adc (patch) | |
| tree | 351d2e8ca05ca1daab1d79b0e8d5045bce8cbcf4 | |
| parent | 6df3d8bf595b3645022b4d465fd1192f9033913e (diff) | |
improve socket accept and connect
| -rw-r--r-- | tests/modules/socket/tcp/echo_client.lua | 2 | ||||
| -rw-r--r-- | tests/modules/socket/tcp/echo_server.lua | 25 | ||||
| -rw-r--r-- | xmake/core/base/socket.lua | 96 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/base/socket.lua | 78 |
4 files changed, 121 insertions, 80 deletions
diff --git a/tests/modules/socket/tcp/echo_client.lua b/tests/modules/socket/tcp/echo_client.lua index 4da40bdc1..28c242bb1 100644 --- a/tests/modules/socket/tcp/echo_client.lua +++ b/tests/modules/socket/tcp/echo_client.lua @@ -3,7 +3,7 @@ import("core.base.socket") function main() local addr = "127.0.0.1" local port = 9001 - print("%s: connect %s:%d ..", sock, addr, port) + print("connect %s:%d ..", addr, port) local sock = socket.connect(addr, port) print("%s: connected!", sock) local send = sock:send("hello") diff --git a/tests/modules/socket/tcp/echo_server.lua b/tests/modules/socket/tcp/echo_server.lua index 7c200989b..58e1956c1 100644 --- a/tests/modules/socket/tcp/echo_server.lua +++ b/tests/modules/socket/tcp/echo_server.lua @@ -1,28 +1,19 @@ import("core.base.socket") function main() + local addr = "127.0.0.1" local port = 9001 local sock = socket.bind(addr, port) sock:listen(20) - local sock_client = nil + print("%s: listening %s:%d ..", sock, addr, port) while true do - print("%s: listening %s:%d ..", sock, addr, port) - local ok = sock:wait(socket.EV_ACPT, -1) - if ok == socket.EV_ACPT then - sock_client = sock:accept() - if sock_client then - print("%s: accepted", sock_client) - local recv, data = sock_client:recv(8192) - if recv == 0 then - print("wait ..") - ok = sock_client:wait(socket.EV_RECV, -1) - print("wait %d", ok) - recv, data = sock_client:recv(8192) - end - print("%s: recv %d, %s", sock_client, recv, data) - sock_client:close() - end + local sock_client = sock:accept() + if sock_client then + print("%s: accepted", sock_client) + local recv, data = sock_client:recv(8192) + print("%s: recv %d, data: %s", sock_client, recv, data or "") + sock_client:close() end end sock:close() diff --git a/xmake/core/base/socket.lua b/xmake/core/base/socket.lua index b2be9bc28..971885e6e 100644 --- a/xmake/core/base/socket.lua +++ b/xmake/core/base/socket.lua @@ -89,11 +89,11 @@ function _instance:bind(addr, port) end -- bind it - local result, errors = io.socket_bind(self._SOCK, addr, port, self:family()) - if not result and errors then + local ok, errors = io.socket_bind(self._SOCK, addr, port, self:family()) + if not ok and errors then errors = string.format("%s: %s", self, errors) end - return result, errors + return ok, errors end -- listen socket @@ -106,15 +106,15 @@ function _instance:listen(backlog) end -- listen it - local result, errors = io.socket_listen(self._SOCK, backlog or 10) - if not result and errors then + local ok, errors = io.socket_listen(self._SOCK, backlog or 10) + if not ok and errors then errors = string.format("%s: %s", self, errors) end - return result, errors + return ok, errors end -- accept socket -function _instance:accept() +function _instance:accept(opt) -- ensure opened local ok, errors = self:_ensure_opened() @@ -123,18 +123,27 @@ function _instance:accept() end -- accept it - local result, errors = io.socket_accept(self._SOCK) - if not result and errors then + local sock, errors = io.socket_accept(self._SOCK) + if not sock and not errors then + opt = opt or {} + local events, waiterrs = self:wait(socket.EV_ACPT, opt.timeout or -1) + if events == socket.EV_CONN then + sock, errors = io.socket_accept(self._SOCK) + else + errors = waiterrs + end + end + if not sock and errors then errors = string.format("%s: %s", self, errors) end - if result then - result = _instance.new(self:type(), self:family(), result) + if sock then + sock = _instance.new(self:type(), self:family(), sock) end - return result, errors + return sock, errors end -- connect socket -function _instance:connect(addr, port) +function _instance:connect(addr, port, opt) -- ensure opened local ok, errors = self:_ensure_opened() @@ -143,11 +152,20 @@ function _instance:connect(addr, port) end -- connect it - local result, errors = io.socket_connect(self._SOCK, addr, port, self:family()) - if result < 0 and errors then + local ok, errors = io.socket_connect(self._SOCK, addr, port, self:family()) + if ok == 0 then + opt = opt or {} + local events, waiterrs = self:wait(socket.EV_CONN, opt.timeout or -1) + if events == socket.EV_CONN then + ok, errors = io.socket_connect(self._SOCK, addr, port, self:family()) + else + errors = waiterrs + end + end + if ok < 0 and errors then errors = string.format("%s: %s", self, errors) end - return result, errors + return ok, errors end -- send data to socket @@ -194,11 +212,11 @@ function _instance:wait(events, timeout) end -- wait it - local result, errors = io.socket_wait(self._SOCK, events, timeout or -1) - if result < 0 and errors then + local events, errors = io.socket_wait(self._SOCK, events, timeout or -1) + if events < 0 and errors then errors = string.format("%s: %s", self, errors) end - return result, errors + return events, errors end -- close socket @@ -258,5 +276,45 @@ function socket.open(socktype, family) end end +-- open tcp socket +function socket.tcp(opt) + opt = opt or {} + return socket.open(socket.TCP, opt.family or socket.IPV4) +end + +-- open udp socket +function socket.udp(opt) + opt = opt or {} + return socket.open(socket.UDP, opt.family or socket.IPV4) +end + +-- open and bind tcp socket +function socket.bind(addr, port, opt) + local sock, errors = socket.tcp(opt) + if not sock then + return nil, errors + end + local ok, errors = sock:bind(addr, port) + if not ok then + sock:close() + return nil, string.format("bind %s:%s failed, errors: %s!", addr, port, errors or "") + end + return sock +end + +-- open and connect tcp socket +function socket.connect(addr, port, opt) + local sock, errors = socket.tcp(opt) + if not sock then + return nil, errors + end + local ok, errors = sock:connect(addr, port, opt) + if ok <= 0 then + sock:close() + return nil, string.format("connect %s:%s failed, errors: %s!", addr, port, errors or "") + end + return sock +end + -- return module return socket diff --git a/xmake/core/sandbox/modules/import/core/base/socket.lua b/xmake/core/sandbox/modules/import/core/base/socket.lua index 54f135a4e..6090e52b1 100644 --- a/xmake/core/sandbox/modules/import/core/base/socket.lua +++ b/xmake/core/sandbox/modules/import/core/base/socket.lua @@ -62,47 +62,47 @@ end -- wait socket events function sandbox_core_base_socket_instance.wait(sock, events, timeout) - local result, errors = sock:_wait(events, timeout) - if result < 0 and errors then + local events, errors = sock:_wait(events, timeout) + if events < 0 and errors then raise(errors) end - return result + return events end -- bind socket function sandbox_core_base_socket_instance.bind(sock, addr, port) - local result, errors = sock:_bind(addr, port) - if not result and errors then + local ok, errors = sock:_bind(addr, port) + if not ok and errors then raise(errors) end - return result + return ok end -- listen socket function sandbox_core_base_socket_instance.listen(sock, backlog) - local result, errors = sock:_listen(backlog) - if not result and errors then + local ok, errors = sock:_listen(backlog) + if not ok and errors then raise(errors) end - return result + return ok end -- accept socket -function sandbox_core_base_socket_instance.accept(sock) - local result, errors = sock:_accept() - if not result and errors then +function sandbox_core_base_socket_instance.accept(sock, opt) + local client_sock, errors = sock:_accept(opt) + if not client_sock and errors then raise(errors) end - return result and _socket_wrap(result) or nil + return client_sock and _socket_wrap(client_sock) or nil end -- connect socket -function sandbox_core_base_socket_instance.connect(sock, addr, port) - local result, errors = sock:_connect(addr, port) - if result < 0 and errors then +function sandbox_core_base_socket_instance.connect(sock, addr, port, opt) + local ok, errors = sock:_connect(addr, port, opt) + if ok < 0 and errors then raise(errors) end - return result + return ok end -- send data to socket @@ -142,8 +142,6 @@ end -- open socket function sandbox_core_base_socket.open(socktype, family) - - -- open sock local sock, errors = socket.open(socktype, family) if not sock then raise(errors) @@ -153,44 +151,38 @@ end -- open tcp socket function sandbox_core_base_socket.tcp(opt) - opt = opt or {} - return sandbox_core_base_socket.open(socket.TCP, opt.family or socket.IPV4) + local sock, errors = socket.tcp(opt) + if not sock then + raise(errors) + end + return _socket_wrap(sock) end -- open udp socket function sandbox_core_base_socket.udp(opt) - opt = opt or {} - return sandbox_core_base_socket.open(socket.UDP, opt.family or socket.IPV4) + local sock, errors = socket.udp(opt) + if not sock then + raise(errors) + end + return _socket_wrap(sock) end -- open and bind tcp socket function sandbox_core_base_socket.bind(addr, port, opt) - opt = opt or {} - local sock = sandbox_core_base_socket.open(socket.TCP, opt.family or socket.IPV4) - if sock:bind(addr, port) then - return sock + local sock, errors = socket.bind(addr, port, opt) + if not sock then + raise(errors) end - sock:close() - raise("bind %s:%s failed!", addr, port) + return _socket_wrap(sock) end -- open and connect tcp socket function sandbox_core_base_socket.connect(addr, port, opt) - opt = opt or {} - local sock = sandbox_core_base_socket.open(socket.TCP, opt.family or socket.IPV4) - local ok = sock:connect(addr, port) - if ok == 0 then - ok = sock:wait(socket.EV_CONN, opt.timeout or -1) - if ok == socket.EV_CONN then - ok = sock:connect(addr, port) - end - end - if ok > 0 then - return sock - else - sock:close() - raise("connect %s:%s failed!", addr, port) + local sock, errors = socket.connect(addr, port, opt) + if not sock then + raise(errors) end + return _socket_wrap(sock) end -- return module |
