Luasocket - 如何发送/接收UDP广播消息?

我已经试图做这个了一段时间了。我尝试按照这个http://lua.2524044.n2.nabble.com/UDP-Broadcast-td3995269.html的说明进行,但是没有成功。我已经成功地在客户端与服务器之间发送了单播消息。我确认了我的广播地址是正确的。我能想到的唯一其他的事情就是嗅探我的接口以确保没有网络问题。我明天会解决这个问题,但是想在这里发布这个问题以查看是否有任何愚蠢的错误。

注意:我在同一台笔记本电脑上运行客户端和服务器。

客户端

local socket = require("socket")
local s_address, s_port = "192.168.1.135", 33333
local d_address, d_port = "192.168.1.255", 22222

udp = socket.udp()
assert(udp)
assert(udp:settimeout(1))
assert(udp:setoption('broadcast', true))
assert(udp:setoption('dontroute',true))
assert(udp:setsockname(s_address, s_port))

while true do
  tosend = string.format("客户端%s:%s", s_address, s_port)
  print(string.format('发送到%s:%s...', d_address, d_port))
  udp:sendto(tosend, d_address, d_port)

  data, msg = udp:receive()
  toprint = string.format("数据 = \"%s\"", data)
  print(toprint)
  socket.sleep(.5)
end

服务器

local socket = require("socket")
local s_address, s_port = "192.168.1.135", 11111
local p_address, p_port = "192.168.1.255", 22222

udp = socket.udp()
assert(udp)
assert(udp:setoption('broadcast', true))
assert(udp:setoption('dontroute',true))
assert(udp:settimeout(1))
assert(udp:setsockname(s_address, s_port))
assert(udp:setpeername(p_address, p_port))

while true do
  data = udp:receive()
  print(string.format('监听 %s:%s...', p_address, p_port))
  toprint = string.format("数据 = \"%s\"", data)
  print(toprint)
  if data then
    msg_back = "服务器已接收到您的消息"
    udp:send(msg_back)
  end
  socket.sleep(.5)
end

输出

双方持续打印数据 = "nil"

点赞
用户4970184
用户4970184

我一直在寻找实现 luasocket 广播的方法,这是互联网上唯一提出这个主题的页面之一。最终,在 luasocket API 和一些我可以适应的 python 代码之间,我找到了适合自己的解决方案:

``` local socket = require 'socket' local HOME_ADDR = '192.168.0.1' local SUBNET_PATTERN = '%d+%.%d+%.%d+%.'

local function get_own_address() local s = assert(socket.udp()) assert(s:setpeername(HOME_ADDR, 80)) local host = s:getsockname() s:close() return host end

function broadcast(message, address, port) local broadcaster = assert(socket:udp()) assert(broadcaster:setoption('broadcast', true)) assert(broadcaster:setoption('dontroute', true)) -- do we need this?

print(('Broadcasting %q to %s:%i'):format(message, address, port)) assert(broadcaster:sendto(message, address, port)) broadcaster:close() end

function antiphony(message, timeout, call_port, response_port, response_mask) local message, timeout, mask = tostring(message), tonumber(timeout) or 1.5, response_mask or 'a' local send_port, recv_port = call_port or 10500, response_port or 10501 local broadcast_address = get_own_address():match(SUBNET_PATTERN) .. '255' local listener = assert(socket.bind('', recv_port, 64)) local clients, responses, starttime = {}, {}

listener:settimeout(0) broadcast(message, broadcast_address, send_port) starttime = socket.gettime() repeat clients[listener:accept() or false] = true until socket.gettime() - starttime > timeout

for client in pairs(clients) do if client then responses[client:getpeername()] = tostring(client:receive(mask)) client:close() end end listener:close()

return responses end

function listen(response_callback, timeout, listen_port, reply_port) local recv_port, send_port = tonumber(listen_port) or 10500, tonumber(reply_port) or 10501 local callback = response_callback or function()end local address = get_own_address():match(SUBNET_PATTERN) .. '255' local sleeper = socket.udp()

sleeper:settimeout(timeout) sleeper:setsockname(address, recv_port) repeat local data, ip, port = sleeper:receivefrom(1024) if data then callback(ip, send_port, data) end until not data end

function respond(message, data_handler) return function(ip_addr, port, data) assert(ip_addr and port, ('Invalid address: %s:%s'):format(tostring(ip_addr), tostring(port))) local msg = tostring(type(data_handler) == 'function' and (data_handler(data, message) or messsage) or message) local sender = assert(socket.connect(ip_addr, port)) assert(sender:send(msg)) sender:close() end end

--[[

-- 监听器 / 响应器: listen(respond('polo', print), 600) -- 10 分钟超时

-- 广播器 / 接收器: for address, response in pairs(antiphony('marco')) do print(address, response) end

]]```

2020-04-09 12:52:41