【问题标题】:Send m-search packets on all network interfaces在所有网络接口上发送 m-search 数据包
【发布时间】:2014-06-12 07:17:26
【问题描述】:

我正在实现一个代码,通过它我必须让设备连接到我机器上的所有网络接口。

为此,我首先获取所有网络接口的 ip,然后在它们上发送 m-search 命令。

2.5 秒后端口停止监听。

但它给了我一些断言错误。

Code:

class Base(DatagramProtocol):
    """ Class to send M-SEARCH message to devices in network and receive datagram
        packets from them
    """
    SSDP_ADDR = "239.255.255.250"
    SSDP_PORT = 1900
    MS = "M-SEARCH * HTTP/1.1\r\nHOST: {}:{}\r\nMAN: 'ssdp:discover'\r\nMX: 2\r\nST: ssdp:all\r\n\r\n".format(SSDP_ADDR, SSDP_PORT)

def sendMsearch(self):
    """ Sending M-SEARCH message
    """
    ports = []
    for address in self.addresses:
        ports.append(reactor.listenUDP(0, self, interface=address))

    for port in ports:
        for num in range(4):
            port.write(Base.MS, (Base.SSDP_ADDR,Base.SSDP_PORT))
        reactor.callLater(2.5, self.stopMsearch, port) # MX + a wait margin


def stopMsearch(self, port):
    """ Stop listening on port
    """
    port.stopListening()

Error:

Traceback (most recent call last):
  File "work\find_devices.py", line 56, in sendMsearch
    ports.append(reactor.listenUDP(0, self, interface=address))
  File "C:\Python27\lib\site-packages\twisted\internet\posixbase.py", line 374, in listenUDP
    p.startListening()
  File "C:\Python27\lib\site-packages\twisted\internet\udp.py", line 172, in startListening
    self._connectToProtocol()
  File "C:\Python27\lib\site-packages\twisted\internet\udp.py", line 210, in _connectToProtocol
    self.protocol.makeConnection(self)
  File "C:\Python27\lib\site-packages\twisted\internet\protocol.py", line 709, in makeConnection
    assert self.transport == None
AssertionError

请说明这段代码有什么问题以及如何纠正。

同样在 linux 机器上,如果在网络上没有找到设备,那么它不会去 stopMsearch() 为什么?

【问题讨论】:

  • 我建议打印出正在传递给reactor.listenUDPinterface 参数的地址,看看这是否提供了线索。我也对尝试监听 0 端口感到困惑,你测试过吗?
  • @MikeLutz 我检查了地址,它们是正确的,如果我在它们上单独发送 m-search,它们工作正常。问题是当我试图同时向所有这些发送 m-search 时。
  • 鉴于您的代码 sn-ps,我想不出任何明显的问题,因为有多少是未知的(我怀疑大多数读者也会有相同的反应 - 有大量的细节是没有在您的示例中解决)。考虑在这个问题中记录您的调试实验(即地址检查之类的东西,并包括简化的工作和非工作可运行代码)。通过示例帮助我们更好地了解您的代码/问题的范围,我们将能够提供更高质量的反馈/答案。

标签: python-2.7 twisted assertion reactor ssdp


【解决方案1】:

一个协议只能有一个传输。循环:

for address in self.addresses:
    ports.append(reactor.listenUDP(0, self, interface=address))

尝试创建多个 UDP 传输并将它们全部与 self 相关联 - 单个协议实例。

这就是断言错误告诉你的。协议的传输必须是None(即,它不能有传输)。但是在循环的第二次迭代中,它已经有了一个传输。

尝试使用多个协议实例。

【讨论】:

  • @JeanPaul 你是说要像这样修改代码 - def sendMsearchToAll(self): for address in self.addresses: self.sendMsearch(address) def sendMsearch(self, address): port = reactor.listenUDP(0, self, interface=address) for num in range(4): port.write(Base.MS, (Base.SSDP_ADDR,Base.SSDP_PORT)) reactor.callLater(2.5, self.stopMsearch, port) # MX + a wait margin
  • 那是……难以阅读。但不,我认为这是不对的。我仍然只看到Base 的一个实例(我认为 - 再次,难以阅读)。
  • @JeanPaul 是的,我仍然使用 Base 的一个实例,这是错误的。但是现在我已经为每个接口实现了带有单独 Base 实例的代码,并且它可以工作。谢谢让-保罗
  • @JeanPaul 在 Linux 机器上,如果在网络上找不到设备,那么它不调用 stopMsearch() 为什么?如何调试这个?
  • 您的问题中没有设备查找代码。我不确定你在说什么。也许您想提出一个新问题。
猜你喜欢
  • 1970-01-01
  • 2018-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-23
  • 2013-02-22
相关资源
最近更新 更多