无法在未ping的情况下向UDP IPv6套接字发送数据
我正在写一个程序,用来通过IPv6的UDP端口向一个设备发送和接收数据。我的Python代码是在Windows 7平台上运行的,而这个设备是一个定制的硬件。我的电脑和设备是直接连接的,没有通过局域网。
这个程序有点问题。当我第一次尝试向设备发送消息时,发送失败。具体来说,从wireshark的视角来看,我根本没有看到消息发送到设备上。当我在命令行中用ping <ipv6_addr> -t
来ping这个设备时,前1到2次尝试是失败的,之后就开始收到回应了。我停止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入手,看看能找到什么。
任何帮助都非常感谢!
2 个回答
这里有几个小提示:
在调用
client.bind()
之前,先调用client.setsockopt()
。当你用完这个 socket 时,一定要调用
socket.close()
来关闭它。我怀疑你遇到的 ping 和时间问题,可能是因为超时时间设置得太短,加上 NDP 缓存的原因。超时时间
0.25
可能对 NDP 解析 和数据传输来说太低了(也许你的嵌入式设备处理速度慢)。当你进行 ping 操作时,它会为你执行 NDP,并创建一个缓存信息,这样你就可以在应用中使用,而不会超出超时限制。我建议你试着把超时限制调高:
client.settimeout(2)
经过一番查找,我觉得找到了我的问题所在。我在绑定的时候没有把运行Python的电脑的IP地址包含进去。所以我把上面的connect()函数改成了
def connect(self):
# ...
client.bind(('fe80::', port))
# ...
这样我的消息就能稳定地发送了。我对套接字编程还很陌生,有人能解释一下为什么这个修改有效吗?
谢谢