【问题标题】:Does recvfrom() modify src_addr on error?recvfrom() 是否会在错误时修改 src_addr?
【发布时间】:2015-09-25 20:20:10
【问题描述】:

我目前正在编写一个供个人使用的小型 UDP 套接字库,但我一直无法找到任何相关文档。

我指的函数是 ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);,来自 POSIX <sys/socket.h> 标头。

无论recvfrom 是成功还是失败,我都想重用我传递给recvfrom 的src_addr 结构以与sendto(相同的标头)一起使用。成功后,它将包含发送数据的对等方的地址(我的用例中只有一个),这是预期的行为;但是,当非阻塞读取失败时,它会生成错误EAGAIN,然后src_addr 的状态就不清楚了。如果src_addr 没有被修改,它仍然会包含目标地址并且可以重复使用,但如果是,那么我将不得不使用临时变量。

【问题讨论】:

  • src_addr 的状态未定义” - 你在哪里看到的?
  • @immibis:我没有;这就是为什么我说它是未定义的——据我所知,它在任何地方都没有记录。这不是编程上下文中“未定义”的典型用法(隐式而不是显式),但含义是相同的。尽管如此,我已经更新了问题。
  • 你想多了。只需使用 temp 变量。将其称为“稳健性”、“可移植性”或“向前兼容性”并继续前进。
  • POSIX 表示如果地址由协议指定,则写入源地址,否则其值未指定。就目前而言,并没有严格禁止覆盖源地址(例如,用零),但这是额外的工作,它不会特别有用,所以我怀疑任何实现都会这样做。当然,现在您也可以将措辞解释为“UDP 确实(通常)提供消息地址”,因此地址字段被写入

标签: c++ c sockets udp posix


【解决方案1】:

我刚刚处理了同样的问题。 为了增加您的困惑,我观察到了两种不同的结果:

  • 在 WinCE 5.0 上,recvfrom() 似乎在无法接收字节时将零放入 from 参数
  • 在 On-Time RTOS(声称与 Win* API 兼容)下,from 参数在失败 recvfrom() 时保持不变

我更喜欢 RTOS 的实现,因为我的应用程序采用了惰性方法,将指针指向套接字的已知远程 IP 地址。就像@Techwolf 一样,这个相同的地址后来被用于sendto() 调用中。我花了一段时间才弄清楚为什么相同的代码在 WinCE 下无法运行。

相反,我遵循@Dummy00001 的建议来选择稳健性。 通过使用临时变量,应用程序可以在我的两个平台上运行。

顺便说一下,我的应用程序在某些情况下会“自动检测”远程主机。在这种情况下,临时变量有一个目的。我将它复制回与此套接字关联的永久成员 - 但仅当 recvfrom() 返回正数字节时!

【讨论】:

    猜你喜欢
    • 2017-12-23
    • 2019-07-31
    • 2014-12-29
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 2019-11-30
    • 1970-01-01
    • 2011-07-03
    相关资源
    最近更新 更多