diff options
| author | ruki <[email protected]> | 2019-11-03 22:19:55 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2019-11-03 22:19:55 +0800 |
| commit | 8eddfb0d678d6ea5427ae55e9dff108fde5add42 (patch) | |
| tree | cac98a7120db66447cf48b6b6c1bdf2d05be04a4 /xmake/core/base/socket.lua | |
| parent | b0a7b7a70cafc7988a33e1856147622b0ea92559 (diff) | |
add socket.sendto and socket.recvfrom
Diffstat (limited to 'xmake/core/base/socket.lua')
| -rw-r--r-- | xmake/core/base/socket.lua | 95 |
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) |
