Luasocket - 如何发送/接收UDP广播消息?
2017-9-19 8:24:34
收藏:0
阅读:178
评论:1
我已经试图做这个了一段时间了。我尝试按照这个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"。
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

我一直在寻找实现 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
]]```