summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-10-27 21:08:19 +0800
committerruki <[email protected]>2019-10-27 21:08:19 +0800
commit239d4dead77af769ba5adccb58f30e9d52238adc (patch)
tree351d2e8ca05ca1daab1d79b0e8d5045bce8cbcf4
parent6df3d8bf595b3645022b4d465fd1192f9033913e (diff)
improve socket accept and connect
-rw-r--r--tests/modules/socket/tcp/echo_client.lua2
-rw-r--r--tests/modules/socket/tcp/echo_server.lua25
-rw-r--r--xmake/core/base/socket.lua96
-rw-r--r--xmake/core/sandbox/modules/import/core/base/socket.lua78
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