gpt4 book ai didi

python - Bluez/Python 缓冲导致蓝牙连接延迟

转载 作者:行者123 更新时间:2023-12-05 06:01:27 27 4
gpt4 key购买 nike

我编写了一个 Python 程序,它通过蓝牙套接字(参见下面的示例)读取和写入 L2CAP 连接以与某些硬件通信。然而,代码可能想要为蓝牙适配器做太多的 IO 处理,所以我通过在需要时放慢 bar 循环来装备它来处理滞后的读写,因为这比延迟更可取响应请求。

sock = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP)
sock.connect((bt_addr, bt_port))
sock.setblocking(False)

stall_loop = asyncio.Event()
stall_loop.set()

async def bar():
while True:
await stall_loop.wait()
await loop.sock_sendall(generate_data(time.time()))
await asyncio.sleep(maybe_to_small_delay)

async def foo():
while True:
await request = loop.sock_recv(sock, 400)
stall_loop.clear()
await loop.sock_sendall(generate_response(request))
stall_loop.set()

asyncio.gather(foo, bar)

然而,问题是这些循环都没有看到任何明显的减速,直到 bar 一次卡住几秒钟。

我使用 time.time() 为两个循环的执行计时,执行时间包括 IO 在内只有几毫秒(bar 卡住时除外),但是由foo 最多只能延迟 15 秒发送(由 tshark 报告并与 python 认为写入完成的时间进行比较)

我想要的行为是写入仅在数据实际传输后返回,以保持响应速度 foobar 尽可能接近所需速度可能。

我认为罪魁祸首是某种缓冲策略,它缓冲大量数据直到缓冲区已满,然后将其完全刷新。我怎样才能禁用此 bahviour 和/或将缓冲区大小限制为例如2包?我找不到有关 bluez 的 ioctl 的文档。

版本:

  • 内核 5.10.17-vl7+ 上的 Raspbian
  • python 3.7.3
  • 布鲁兹 5.50

最佳答案

问题是 Linux 中的缓冲,解决方案是禁用它:

client_itr.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 0)

今天在 GNU libc docs 中找到这个选项.

我不知道为什么它决定在缓冲区填满后完全刷新缓冲区(这导致 bar-loop 卡住了一段时间),但没有缓冲行为是预期的:在 foo 收到请求和发送回复之间最多有 2 个 bar 数据包,即使没有 Event 锁定。

但是请注意,如果没有缓冲,sendall 只会阻塞,直到数据通过蓝牙发送,直到接收方确认。为此,您可能必须降低 L2CAP 的窗口大小。

关于python - Bluez/Python 缓冲导致蓝牙连接延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67185675/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com