python - 强制非阻塞 UDP 套接字在 sendto 上引发 BlockingIOError
问题描述
我相信非阻塞 UDP 套接字可以在 sendto 上引发 BlockingIOError。我想强制这种情况来测试我的程序在这种情况下的行为。
sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
sock.setblocking(False)
sock.bind(('', 7777))
...
# Even if repeating in a loop, doesn't seem to raise a BlockingIOError
sock.sendto(b'abcde', ('1.2.3.4', 61908))
我尝试将传出缓冲区设置为小
buffer_size = 5
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, buffer_size)
但它要么似乎没有影响,要么导致OSError: [Errno 40] Message too long
缓冲区小于数据。
我的信念是错误的:它永远不会引发 BlockingIOError 吗?或者如果可以,我该如何强制?
我的目标是进行集成式测试:我想实际拥有一个真正的套接字并进行实际的网络调用。在这种情况下模拟单元式测试的套接字并不理想。
套接字只能在单线程 Python asyncio 程序中使用。
解决方案
摘自 C 语言中的 TCP/IP 套接字:程序员实用指南,Michael J. Donahoo,Kenneth L. Calvert
对于 UDP 套接字,没有发送缓冲区,因此
send()
永远sendto()
不会返回EWOULDBLOCK
从https://linux.die.net/man/2/sendto有一个关于为什么的提示......
当设备队列溢出时,数据包会被静默丢弃。
因此,在 Python 术语中,BlockingIOError
至少在 Linux 上不能提出。
推荐阅读
- python - 如何在lambda python函数中将json数组转换为json对象
- python - 缺少 AppSink 方法:AttributeError:“GstAppSink”对象没有属性“is_eos”
- node.js - 我在哪里可以获得 Watson-Assistant 的“workspace_id”参数?
- antlr4 - ANTLR中具有贪婪通配符和转义字符的字符串词法规则
- javascript - 如何隔离 javascript 并将其绑定到特定表单
- c++ - libxml2 的 cmake find_package 不返回有效的头目录
- r - 调度 R 脚本以在 Mac 上使用 crontab 运行
- javascript - 使用pm2启动一个node app,那个node app fork一个子进程,当子进程down掉时,pm2会重启node app吗?
- cplex - CPLEX 无法解决 Gurobi 可以解决的 .lp 文件
- typescript - 如何比较 getMonth() 和完整的日期格式?