我想从服务器向客户端传输数据(多张大小 > 3 MB 的图像)。由于我想测试没有重传的丢包,所以我不想使用流(TCP)。
我经历了这个example .我的方法是,服务器使用 f.read(1024)
读取数据 block 并使用 transport.sendto(data + seq_num)
发送给客户端。读取和发送将循环进行,直到文件结束。
客户端将通过 datagram_received(self, data, addr):
接收。由于我在数据中发送序列号 (seq_num),因此我可以控制丢失的段和顺序.我的问题是在客户端接收和写入数据。如何使用 datagram_received (self, data, addr)
函数在客户端存储不同时间从服务器发送的数据?
是否有用于从 sock 接收数据到 buf 缓冲区的功能?例如,对于流 (TCP) data = await loop.sock_recv(tcp_sock, buf)
。感谢您的帮助。
最佳答案
Is there a feature that used to receive data from sock into the buf buffer? e.g for stream (TCP)
data = await loop.sock_recv(tcp_sock, buf)
.
正如评论中所指出的,数据报无法提供真正的流接口(interface),因为 UDP 不保证传递顺序。如果我对问题的理解正确,您会希望有一个可等待接口(interface)来处理下一个 UDP 数据包的传送事件,因为默认提供的接口(interface)完全基于回调。
幸运的是,将基于回调的接口(interface)转换为可等待的接口(interface)非常容易 - asyncio
通常为此目的使用 Future
,协程等待 future ,并且回调调用 set_result()
将一些数据传递给等待协程 - 请参阅 sample UDP client 中的 on_con_lost
来自文档。
一个好的流式 API 总是支持某种形式的缓冲,这可以由容量有限的队列提供:
class Client:
def __init__(self):
self._received = asyncio.Queue(10)
...
async def read_packet(self):
return await self._received.get()
def datagram_received(self, data, addr):
try:
self._received.put_nowait((data, addr))
except asyncio.QueueFull:
log.error(f"dropped packet size {len(data)} from {addr}")
有限大小的队列允许数据处理暂时慢于数据到达的速度,同时防止内存泄漏,以防情况继续发生。队列填满后,数据包将被丢弃。 (对于 TCP/IP 支持的流,我们会减慢读取速度以提供背压 - 在 this article 中有很好的解释,但对于 UDP,除了放弃别无选择。)
关于python - 如何将 UDP 与 Asyncio 一起用于从服务器到客户端的多个文件传输 - python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53733140/