summaryrefslogtreecommitdiff
path: root/xmake/core/base/socket.lua
diff options
context:
space:
mode:
authorruki <[email protected]>2019-11-03 22:19:55 +0800
committerruki <[email protected]>2019-11-03 22:19:55 +0800
commit8eddfb0d678d6ea5427ae55e9dff108fde5add42 (patch)
treecac98a7120db66447cf48b6b6c1bdf2d05be04a4 /xmake/core/base/socket.lua
parentb0a7b7a70cafc7988a33e1856147622b0ea92559 (diff)
add socket.sendto and socket.recvfrom
Diffstat (limited to 'xmake/core/base/socket.lua')
-rw-r--r--xmake/core/base/socket.lua95
1 files changed, 95 insertions, 0 deletions
diff --git a/xmake/core/base/socket.lua b/xmake/core/base/socket.lua
index 26ca2b2e8..06820522c 100644
--- a/xmake/core/base/socket.lua
+++ b/xmake/core/base/socket.lua
@@ -346,6 +346,101 @@ function _instance:recv(size, opt)
return recv, data_or_errors
end
+-- send udp data to peer
+function _instance:sendto(data, addr, port, opt)
+
+ -- ensure opened
+ local ok, errors = self:_ensure_opened()
+ if not ok then
+ return -1, errors
+ end
+
+ -- check address
+ if not addr or not port then
+ return -1, string.format("%s: sendto empty address!", self)
+ end
+
+ -- send it
+ opt = opt or {}
+ local send = 0
+ local wait = false
+ local errors = nil
+ if opt.block then
+ while true do
+ send, errors = io.socket_sendto(self._SOCK, data, addr, port, self:family())
+ if send == 0 and not wait then
+ local events, waiterrs = self:wait(socket.EV_SEND, opt.timeout or -1)
+ if events == socket.EV_SEND then
+ wait = true
+ else
+ errors = waiterrs
+ break
+ end
+ else
+ break
+ end
+ end
+ else
+ send, errors = io.socket_sendto(self._SOCK, data, addr, port, self:family())
+ if send < 0 and errors then
+ errors = string.format("%s: %s", self, errors)
+ end
+ end
+ return send, errors
+end
+
+-- recv udp data from peer
+function _instance:recvfrom(size, opt)
+
+ -- ensure opened
+ local ok, errors = self:_ensure_opened()
+ if not ok then
+ return -1, errors
+ end
+
+ -- check size
+ if size == 0 then
+ return 0
+ elseif size == nil or size < 0 then
+ return -1, string.format("%s: invalid size(%d)!", self, size)
+ end
+
+ -- recv it
+ opt = opt or {}
+ local recv = 0
+ local wait = false
+ local data_or_errors = nil
+ if opt.block then
+ while true do
+ recv, data_or_errors, addr, port = io.socket_recvfrom(self._SOCK, size)
+ if recv > 0 then
+ data_or_errors = bytes(data_or_errors)
+ break
+ elseif recv == 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
+ recv = -1
+ data_or_errors = waiterrs
+ break
+ end
+ else
+ break
+ end
+ end
+ else
+ recv, data_or_errors, addr, port = io.socket_recvfrom(self._SOCK, size)
+ if recv > 0 then
+ data_or_errors = bytes(data_or_errors)
+ end
+ end
+ if recv < 0 and data_or_errors then
+ data_or_errors = string.format("%s: %s", self, data_or_errors)
+ end
+ return recv, data_or_errors, addr, port
+end
+
-- wait socket events
function _instance:wait(events, timeout)