使用Python套接字每秒发送100个UDP数据包,如何减少延迟?
我正在通过网络编写一个实时音频共享工具,我首先尝试使用UDP数据包(稍后我将使用TCP进行研究,但我首先希望看到使用UDP可以获得的最佳效果) 在下面的代码中,使用Python套接字每秒发送100个UDP数据包,如何减少延迟?,python,windows,sockets,udp,latency,Python,Windows,Sockets,Udp,Latency,我正在通过网络编写一个实时音频共享工具,我首先尝试使用UDP数据包(稍后我将使用TCP进行研究,但我首先希望看到使用UDP可以获得的最佳效果) 在下面的代码中,txmax是在已发送的最后100个数据包中发送单个UPD数据包(大小约1800字节)所花费的最大时间。我观察到: txmax通常在6毫秒到20毫秒的范围内,这是正常的 但是每分钟有一到两次,txmax峰值为250毫秒,即至少有一个sock。sendto(…)发送一个1.8 KB的UDP数据包需要250毫秒 问题:原因可能是什么?如
txmax
是在已发送的最后100个数据包中发送单个UPD数据包(大小约1800字节)所花费的最大时间。我观察到:
通常在6毫秒到20毫秒的范围内,这是正常的txmax
- 但是每分钟有一到两次,
峰值为250毫秒,即至少有一个txmax
发送一个1.8 KB的UDP数据包需要250毫秒强>sock。sendto(…)
socket
library减少UDP发送延迟?
注:
- 我的家庭Wifi网络可能不是瓶颈,我只发送~100个数据包x 1.8 KB=180 KB/秒~1.4 Mbit/秒
- 我已经尝试在
REALTIME\u PRIORITY
但这并没有改变任何事情import psutil, os psutil.Process(os.getpid()).nice(psutil.REALTIME_PRIORITY_CLASS)
- 我已经尝试增加套接字的发送缓冲区大小:
但影响很小sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 16384)
- 如果我同时运行另一个进程,CPU达到峰值,那么这个问题就更明显了
似乎改变了这种情况:延迟现在为零,或者非常接近,但代码有时会完全停止,原因是:sock.setblocking(False)
BlockingIOError: [WinError 10035] A non-blocking socket operation could not be completed immediately
可复制示例:
import time, socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
txmax = 0
i = 0
while True:
# data = getdatachunk() # this is always stable and takes ~ 10ms with no exception
# for reproducibility, replaced with:
time.sleep(0.010)
data = b'A' * 1800
s = time.time()
sock.sendto(data, ("192.168.1.17", 5006)) # send UDP packet
txmax = max(txmax, time.time() - s)
if i % 100 == 0:
print(txmax)
txmax = 0
i += 1
经过广泛的测试,两件事大大改善了结果:
- 设置超时:
这样,就没有更多的问题了:sock.settimeout(0.050)
一直下降到1ms,250ms时不再有峰值 我甚至从未经历过上述例外情况: socket.settimeout(值)txmax
设置阻止套接字操作的超时。value参数可以是表示秒的非负浮点数,也可以是None。如果给定了非零值,则如果超时时间值在操作完成之前已过,则后续套接字操作将引发超时异常。如果给定零,则将套接字置于非阻塞模式。如果未给出任何值,则将套接字置于阻塞模式 - 至于录音部分(这里不谈这个话题),我终于注意到了
彻底解决了音频爆裂的问题import psutil, os; psutil.Process(os.getpid()).nice(psutil.REALTIME_PRIORITY_CLASS)
212992
。我试着在我的系统上运行你的代码,我得到的大部分是0.00015
即0.2ms(这仍然让我有点惊讶。ping
以太网的往返时间是~0.4ms。我认为这个UDP传输应该只是得到缓冲,而不是等待,除非缓冲区填满)。300秒后,我看不到任何超过0.6毫秒的东西。感谢您运行这些测试@sourcejedi!也许在Windows上,socket
的优先级较低?(我将在几秒钟内更新问题,使用“阻塞”与“不阻塞”测试)