【问题标题】:Not able to send data to a UDP IPv6 socket until I ping在我 ping 之前无法将数据发送到 UDP IPv6 套接字
【发布时间】:2014-05-08 01:02:59
【问题描述】:

我正在编写一个程序来使用 IPv6 UDP 端口向设备发送/接收数据。我的 python 代码在 Win7 平台上运行,该设备是一块定制硬件。 PC 和设备直接连接,不通过 LAN 路由。

程序工作......有点。当我最初尝试向设备发送消息时,发送失败。更具体地说,正如wireshark所看到的,我从来没有看到消息被发送到设备。当我在命令行上使用ping <ipv6_addr> -t ping 设备时,前 1 或 2 次尝试失败,之后开始接收 ping。我像以前一样终止 ping 并尝试发送消息,但现在它成功了。 Wireshark 现在显示所有消息。如果我在相对较短的时间内(在 10 秒到 2 分钟之间)继续发送消息,则程序按预期工作。如果我再等一会儿,我的消息将再次发送不出去。如果我让 ping 程序持续 ping,那么无论消息发送活动之间的时间如何,我的消息也会被发送。这是我的代码:

import socket

def connect(port):
    if socket.has_ipv6:  
        client = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)   
        client.bind(('', port))
        client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        client.settimeout(0.25)

def send_data(addr, port, data):
    client.sendto(data, (addr, port))

def main_app():
    connect(10000)
    bin_data = binascii.a2b_hex('deadbeef')

    # Do some processing
    send_data(<ipv6_address>, 10000, bin_data)

一些谷歌搜索并没有很好地确定问题是 Python 还是其他问题,所以我想我会从 Python 开始,看看它会把我带到哪里。

任何帮助将不胜感激!

【问题讨论】:

  • 对我来说听起来像是某种节电问题...您的设备可能正在进入节电模式(可能只有网卡),直到它接收到一些流量。这是否也只发生在 IPv6 或 IPv4 上?

标签: python sockets udp ping ipv6


【解决方案1】:

几个提示:

  • 在拨打client.bind()之前先拨打client.setsockopt()。

  • 您需要在使用完套接字后调用socket.close()。

  • 我怀疑 ping 和计时问题的奇怪问题背后的原因可能是低超时值和 NDP 缓存的组合。 0.25 的超时可能由于某种原因太低而无法完成 NDP resolution + 数据传输(可能您的嵌入式设备堆栈很慢)。当您执行 ping 操作时,它会为您执行 NDP,并创建一个您可以从您的应用程序中使用的缓存信息,而不会超出超时限制。

    我建议尝试提高限制:client.settimeout(2)

【讨论】:

  • 劳伦斯,感谢您的建议。我添加了您的所有更改,但没有任何区别。如果数据要添加到讨论中,还有一点。有时在几秒钟内重复尝试发送消息会迫使它们实际发送。但是,我只看到过一两次,而且是在收到 ping 响应之后。
【解决方案2】:

经过一番挖掘,我相信我找到了我的问题。我的绑定语句中没有包含运行 python 的 PC 的 IP 地址。所以将上面的 connect() 函数更改为

def connect(self):
    # ... 
    client.bind(('fe80::', port))
    # ...

允许我的消息被一致地发送。我对套接字编程很陌生,所以任何人都可以解释为什么这个修复有效吗?

谢谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多