【问题标题】:edge-triggered epoll and UDP's recvfrom()边缘触发的 epoll 和 UDP 的 recvfrom()
【发布时间】:2016-07-08 12:21:54
【问题描述】:

我一直在努力学习边沿触发epoll 编程。我对在epoll_wait 之后应该如何循环recv 直到它返回EAGAIN 感到困惑——这是否意味着我应该循环recvfrom 直到它返回@987654326 @也一样?如果是这样,这意味着我将不得不缓冲 UDP 数据包,以防我的应用程序尝试读取的字节数少于接收到的字节数。而且,如果我循环recvfrom,我可能会从不同的来源获得多个数据包——我还必须缓冲sockaddrs。这是真的?

【问题讨论】:

  • 一个问题太多了。请简化和结构化你想要的东西
  • 请注意,UDP 套接字的 recvfrom() 为您提供准确的 1(如果调用失败,则为 0)数据包。如果您不为整个数据包提供空间,多余的字节将永远丢失。

标签: linux sockets udp epoll


【解决方案1】:
  1. 是的,您应该循环直到出现EAGAIN=EWOULDBLOCK。您必须在此套接字描述符上设置 O_NONBLOCK 才能实现。
  2. 您无法接收部分 UDP 数据包。
  3. 您可以在下次需要时返回事件循环并从该套接字接收,但请注意,当套接字接收到不是以EAGAIN 结尾的数据包时,内核可能不会唤醒您的epol_wait
  4. 在循环到 EAGAIN 时,请记住,为了防止 reader starvation,您应该保存在此 FD 上接收未完成的信息,例如收到 100 个数据包。之后,您应该尝试另一个 FD。当您决定返回事件循环时,只需分析保存的信息并尝试接收未收到的数据包。
  5. 我不明白你想对sockaddr 说什么。

【讨论】:

  • 对于 (4),我的意思是如果我在 recvfrom 上循环,难道不能从 2 个不同的源地址接收 2 个数据包吗?因此,如果我上面的应用程序正在等待接收 1 个数据包,但通过循环我从 recvfrom 获得了两个数据包,我必须在某处缓冲第二个数据包,直到应用程序要求接收另一个数据包,对吧?
  • @atanamir 是的,这是可能的。使用recvfrom()。您可以在接收后立即处理数据包,然后接收第二个数据包。或者,您可以缓冲所有数据包,直到达到某些标准。如何设计程序取决于您。
猜你喜欢
  • 2014-10-14
  • 2013-01-25
  • 1970-01-01
  • 1970-01-01
  • 2012-02-28
  • 1970-01-01
  • 2014-02-02
  • 1970-01-01
  • 2013-01-16
相关资源
最近更新 更多