【问题标题】:UDP - Read data from the queue in chunksUDP - 以块的形式从队列中读取数据
【发布时间】:2013-03-05 00:32:12
【问题描述】:

我正在使用 UDP(C 语言)实现一个小型应用程序。服务器以给定数量的块(例如 100 字节/调用)将给定文件中的数据发送给客户端。客户端下载文件并将其保存在某处。问题是客户端可以接收一个参数,说明要读取/调用多少字节。
我的问题是当服务器发送 100 字节/调用,而客户端设置为只读 15 字节/调用。其他 85 个字节丢失,因为消息已从 UDP 队列中删除。

有没有办法以块的形式读取这些消息,而无需将它们从队列中删除,直到它们被完全读取?

【问题讨论】:

  • 更改您的客户端服务器协议以避免两端相互混淆
  • 那很好,但我没有创建协议。我必须为我的计算机网络课程和协议做这个小应用程序。
  • 好吧,让我换一种说法。 “当服务器发送 100 字节/调用,而客户端设置为只读 15 字节/调用”您必须控制一端或另一端。只是不要设置客户端和服务器读取错误的字节数!
  • 真正的问题是,为什么客户端只读取 15 个字节开始?显然,该协议需要比所使用的更大的缓冲区。

标签: c sockets udp datagram


【解决方案1】:

UDP 不允许像 TCP 那样进行分块读取。读取 UDP 消息是一个全有或全无的操作,您要么完整阅读整个消息,要么根本不阅读。中间没有。因此,基于 UDP 的协议要么使用固定大小的消息,要么要求双方动态协商消息大小(例如 TrivialFTP 所做的)。

UDP 协议没有理由要求为每条消息发送一个字节大小。消息大小本身隐含地决定了消息内部数据的大小。

如果您在实际读取消息之前绝对必须确定消息大小,您可以尝试使用MSG_PEEK 标志调用recvfrom(),并给它一个大缓冲区以将数据复制到(至少64K,这是一个UDP消息永远不会超过,除非您使用的是 IPv6 Jumbograms,但这是一个单独的问题)。输出将告诉您仍在队列中的消息的实际大小。但是,如果你走这条路,那么你也可以直接删除MSG_PEEK 标志并始终使用 64K 缓冲区进行读取,这样就不会因为缓冲区大小不足而丢失数据。

【讨论】:

  • 感谢您的回答。这与我在研究问题时得到的结论相同。 +1 很好的解释。
【解决方案2】:

您可以创建一个线程从 UDP 缓冲区无限读取数据并将数据保存到循环缓冲区。比客户端以您的速度消耗数据。如果 Buffer 溢出,你什么也做不了。因为服务器的发送速度比客户端的快。

【讨论】:

    猜你喜欢
    • 2018-04-06
    • 2011-03-31
    • 2016-05-27
    • 2019-04-16
    • 1970-01-01
    • 2012-08-18
    • 2014-01-04
    • 2014-07-23
    • 2021-03-25
    相关资源
    最近更新 更多