Python 套接字:接收帧队列管理
Python sockets: received frames queue management
我正在为飞行模拟器创建仪表板。 sim 通过 UDP 发送数据,面板解析该数据并使用它来转换和渲染 SVG。该面板在 Linux.
上运行
sim 发送 UDP 帧的速度比面板可以渲染的速度快,因此帧排队,面板最终比 sim 滞后几秒钟。除了 the MSG_PEEK
flag 之外,我还没有找到关于如何配置或管理此队列的任何建议,这与我想要的完全相反。
每个 UDP 帧都包含完整的 key/value 对,因此理想情况下,我会在收到新帧时丢弃队列中的任何旧帧。
我该怎么做:
- 读取下一帧并丢弃队列中任何后面的帧
- 读取最近的帧并丢弃其余帧
- 将队列大小设置为 1 或较小的数字
我确信有一个简单的方法可以做到这一点,但是一个小时左右的搜索和实验还没有找到解决方案。
这是当前面板代码的表示:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("",54321))
sock.settimeout(0.5)
while True:
try:
frame = sock.recv(1024)
parse_and_render(frame)
except socket.timeout:
pass
这很丑但有效:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("",54321))
sock.setblocking(False)
frame = bytearray(b" " * 1024)
extra_frame = bytearray(b" " * 1024)
while True:
try:
# load next available frame
sock.recv_into(frame, 1024) != -1
# if there's any more frames available, overwrite with that
try:
while sock.recv_into(extra_frame, 1024) != -1:
frame = extra_frame
except BlockingIOError:
pass
# render the most recent frame
parse_and_render(frame)
except BlockingIOError:
pass
我正在为飞行模拟器创建仪表板。 sim 通过 UDP 发送数据,面板解析该数据并使用它来转换和渲染 SVG。该面板在 Linux.
上运行sim 发送 UDP 帧的速度比面板可以渲染的速度快,因此帧排队,面板最终比 sim 滞后几秒钟。除了 the MSG_PEEK
flag 之外,我还没有找到关于如何配置或管理此队列的任何建议,这与我想要的完全相反。
每个 UDP 帧都包含完整的 key/value 对,因此理想情况下,我会在收到新帧时丢弃队列中的任何旧帧。
我该怎么做:
- 读取下一帧并丢弃队列中任何后面的帧
- 读取最近的帧并丢弃其余帧
- 将队列大小设置为 1 或较小的数字
我确信有一个简单的方法可以做到这一点,但是一个小时左右的搜索和实验还没有找到解决方案。
这是当前面板代码的表示:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("",54321))
sock.settimeout(0.5)
while True:
try:
frame = sock.recv(1024)
parse_and_render(frame)
except socket.timeout:
pass
这很丑但有效:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("",54321))
sock.setblocking(False)
frame = bytearray(b" " * 1024)
extra_frame = bytearray(b" " * 1024)
while True:
try:
# load next available frame
sock.recv_into(frame, 1024) != -1
# if there's any more frames available, overwrite with that
try:
while sock.recv_into(extra_frame, 1024) != -1:
frame = extra_frame
except BlockingIOError:
pass
# render the most recent frame
parse_and_render(frame)
except BlockingIOError:
pass