【问题标题】:luasocket send UDP data from port 1900luasocket 从 1900 端口发送 UDP 数据
【发布时间】:2018-06-26 13:33:30
【问题描述】:

我正在尝试从我的家庭自动化控制器模拟 Belkin wemo 开关,以从亚马逊 Echo 发送语音命令。控制器支持 lua 语言。

我正在跟进file,将 UDP 数据从 Controller 的 1900 端口发送到 Echo 的 50000 端口。现在每次我发送数据时,Socket 都会使用随机端口发送数据,而不是从端口 1900 发送数据。Echo 仅在数据来自端口 1900 时才进行有效连接并回复。我从最近两天开始摸不着头脑,让工作正常但还没想通。

下面是我的代码。

strData1 =
  'HTTP/1.1 200 OK' .. 
 'HOST: 239.255.255.250:1900'..
 'CACHE-CONTROL: max-age=100'..
 'EXT:'..
 'LOCATION: http://192.168.1.152:49153/description.xml'..
 'SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.19.0'..
 'hue-bridgeid: B8AC6FFFFEC53475'..
 'ST: upnp:rootdevice'..
 'USN: uuid:2f402f80-da50-11e1-9b23-b8ac6fc53475::upnp:rootdevice'

 local socket = require "socket"
 local udp = socket.udp()

 udp:settimeout(0)
 udp:setsockname('*', 1900)
 udp:setpeername('192.168.1.102', 50000) -- Echo IP and Port number
 udp:sendto(strData1,'192.168.1.102',50000)

【问题讨论】:

  • 首先,我建议您将所有udp 函数调用包装在assert 中,以确保一切正常。其次,您将超时值设置为0,这意味着它每次都会超时。将其设置为正值 udp:settimeout(1) 或 nil 如果您希望它无限期阻止。
  • 改变了 udp:settimeout(1) 的作用。现在还提出断言,我在设置套接字名称(udp:setsockname('*',1900))时收到错误消息“地址已在使用中”。如果系统正在运行,如何关闭套接字?
  • 基于this你必须使用close函数。另外,我建议您将该函数与select 结合使用,以获得一个准备好读取的套接字列表和一个准备好写入的套接字列表。
  • @kingJulian “选择”功能在哪里?
  • 它在链接中,但让我们把它交给chat

标签: sockets lua udp luasocket


【解决方案1】:

你快到了:documentation 声明当使用setpeername 时,必须使用send 而不是sendto

另外,我猜这是一个错字,但您尝试发送 Data 而不是 strData1。这是修正后的版本:

strData1 =
  'HTTP/1.1 200 OK' .. 
 'HOST: 239.255.255.250:1900'..
 'CACHE-CONTROL: max-age=100'..
 'EXT:'..
 'LOCATION: http://192.168.1.152:49153/description.xml'..
 'SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.19.0'..
 'hue-bridgeid: B8AC6FFFFEC53475'..
 'ST: upnp:rootdevice'..
 'USN: uuid:2f402f80-da50-11e1-9b23-b8ac6fc53475::upnp:rootdevice'

 local socket = require "socket"
 local udp = socket.udp()

 udp:settimeout(0)
 udp:setoption('reuseaddr',true)
 udp:setsockname('*', 1900)
 udp:setpeername('192.168.1.102', 50000) -- Echo IP and Port number
 udp:send(strData1)

tcpdump的抓包显示源端口正确:

22:40:45.653222 IP my.super.secret.ip.1900 > 192.168.1.102.50000: UDP, length 280

【讨论】:

  • 您没有将 IP:port 提供给send()。关于 send/sendto 的规则很奇怪。您可以在 BSD 套接字级别使用任何一种,但如果连接,您只是不提供 IP:port 到 sendto(): 只是一个空地址指针。也许这在 LUA 源代码中是不可能的。
  • 我在“udp:setsockname('*', 1900)”这一行收到错误。上面写着“已经在端口 1900 上运行套接字”。我没有在端口 1900 上创建任何套接字。我不知道套接字名称,所以我不能使用 close() 函数。如何获取正在运行的套接字列表?或者我们可以强制关闭 1900 端口上的套接字吗?我在 API 中找不到任何东西:(
  • @Prakash.DTI 您必须使用关闭功能,并进行必要的调整以使其成为可能。
  • 通常我们关闭我们之前启动的套接字... udp = socket.udp() 然后我们使用 udp:close() 关闭套接字但是正在工作的系统是当我执行“udp:setsockname('*', 1900)”时,linux 家庭自动化控制器表示套接字已经在该端口上运行。如何获取 Socket 名称以在其上使用 close() 函数?
  • 看起来您已经在该端口上监听了一个守护进程。在 lua 文件中绑定您的私有 ip(而不是 *),或者让守护程序在专用 ip 上侦听。或者为了更简单,只需终止这些进程以进行测试即可。
猜你喜欢
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 2013-06-24
  • 1970-01-01
  • 2021-10-02
  • 2015-04-20
相关资源
最近更新 更多