问题描述
我正在使用 UDP(在 C 中)实现一个小型应用程序.服务器将给定文件中的数据以给定数量(例如 100 字节/调用)的块发送给客户端.客户端下载文件并将其保存在某处.问题是客户端可以接收一个参数,说明要读取/调用多少字节.
我的问题是当服务器发送 100 个字节/调用,而客户端设置为只读 15 个字节/调用时.其他 85 个字节丢失,因为消息已从 UDP 队列中删除.
I'm implementing a small application using UDP (in C). A server sends to a client the data from a given file in chunks of given amount (ex. 100 bytes / call). The client downloads the file and saves it somewhere. The catch is that the client can receive a parameter saying how many bytes to read / call.
My problem is when the server sends 100 bytes / call, and the client is set to read only 15 bytes / call. The other 85 bytes are lost, because the message is removed from the UDP queue.
有没有办法分块读取这些消息,而无需将它们从队列中移除,直到它们被完全读取?
Is there a way to read these messages in chunks without removing them from the queue until they're completely read?
推荐答案
UDP 不像 TCP 那样允许分块读取.读取 UDP 消息是一个全有或全无的操作,您要么完整地读取整个消息,要么根本不读取整个消息.没有中间.因此,基于 UDP 的协议要么使用固定大小的消息,要么要求双方动态协商消息大小(例如 TrivialFTP).
UDP does not allow for chunked reading like TCP does. Reading a UDP message is an all-or-nothing operation, you either read the whole message in full or none of it at all. There is no in-between. Because of that, UDP-based protocols either use fixed-sized messages, or require both parties to dynamically negotiate the message sizes (like TrivialFTP does, for example).
UDP 协议没有理由要求为每条消息发送一个字节大小.消息大小本身隐含地指示了消息内部数据的大小.
There is no reason for a UDP protocol to require sending a byte size for each message. The message size itself implicitly dictates the size of the data inside of the message.
如果您在实际读取消息之前绝对必须确定消息大小,您可以尝试使用 MSG_PEEK
标志调用 recvfrom()
,并为其提供一个大缓冲区以将数据复制到(至少 64K,UDP 消息永远不会超过,除非您使用 IPv6 Jumbograms,但这是一个单独的问题).输出将告诉您仍在队列中的消息的实际大小.但是,如果你走这条路,那么你也可以放弃 MSG_PEEK
标志并始终使用 64K 缓冲区读取,这样就不会有由于缓冲区大小不足而丢失数据的可能性.
If you absolutely must determine the message size before actually reading the message, you could try calling recvfrom()
with the MSG_PEEK
flag, and give it a large buffer to copy data into (at least 64K, which a UDP message will never exceed, unless you are using IPv6 Jumbograms, but that is a separate issue). The output will tell you the actual size of the message that is still in the queue. However, if you go this route, then you may as well just drop the MSG_PEEK
flag and always read using 64K buffers so there is no possibility of dropping data due to insufficient buffer sizes.
这篇关于UDP - 从队列中分块读取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!