【发布时间】:2021-05-27 17:58:40
【问题描述】:
我有一个用 python 编写的 udp 客户端函数,在 Windows 10 上运行。我知道这不是生产质量代码,但我只是想掌握这里的基础
client = socket(AF_INET, SOCK_DGRAM)
client.bind(('192.168.0.107', CLIENT_PORT))
client.setblocking(False)
while True:
try:
data = client.recv( 1024 )
except:
continue
if data is not None:
print(data.decode('utf-8'))
我有一个在嵌入式设备上运行的服务器,它定期发送小型 udp 数据包(udp 有效负载大小为 22)。这个客户端得到大约 10 个这样的数据包给或拿几个然后脚本停止接收 udp 数据包。在 try/catch 块中引发的唯一异常是没有数据要接收。如果我改为阻止行为是一样的。
[WinError 10035] A non-blocking socket operation could not be completed immediately
服务器仍在发送数据包,我可以在 Wireshark 中看到它们以及预期的 IP 地址、端口和经过验证的校验和。
问题是,如果我在接收停止后添加发送,问题就会完全消失,我可以继续接收 udp 有效负载
client = socket(AF_INET, SOCK_DGRAM)
client.bind(('192.168.0.107', CLIENT_PORT))
client.setblocking(False)
while True:
try:
data = client.recv( 1024 )
except:
continue
if data is not None:
print(data.decode('utf-8'))
client.sendto("a_udp_payload".encode('utf-8'), ('192.168.0.108' , SERVER_PORT))
我在这里缺少一些基本的东西吗?为什么停止在第一个 sn-p 而不是第二个上工作?是否存在一些缓冲区刷新问题?
非常感谢
【问题讨论】:
-
您的 Windows 10 机器上是否启用了防火墙?如果禁用防火墙,故障会消失吗? (这听起来很像防火墙阻止传入的 UDP 数据包的行为,除了来自本地程序在过去 n 秒内将传出数据发送到的 IP 地址的数据包)
-
另外,当使用 UDP 时,你真的应该使用
recvfrom()而不是recv(),除非你connect()到特定 UDP 对等方的套接字(你没有这样做)。这也会给你发件人的address,你可以sendto()返回 -
@Jeremy 为这个建议干杯。我不知道这是防火墙的行为。当这个问题首次出现时,我之前已经为 udp 流量打开了端口。根据您的建议,我在专用网络和域网络上完全禁用了防火墙,但无济于事。这可能是路由器防火墙问题吗?虽然我的印象是路由器防火墙只影响公共网络。
-
@Jeremy 看来我必须允许 python 应用程序通过防火墙,即使通过更改
Control Panel\System and Security\Windows Defender Firewall\Allowed apps中的设置禁用私有和域防火墙也是如此。