【问题标题】:Formal Parameters difference between sendto() and recvfrom() in CC中sendto()和recvfrom()之间的形式参数区别
【发布时间】:2020-02-15 10:46:45
【问题描述】:

我正在使用recvfrom()sendto() 来接收和发送UDP 数据包。

我注意到recvfrom() 作为最后一个参数需要指向变量的指针 来存储服务器地址的长度,而sendto() 需要变量 来存储长度客户地址。

为什么会有这种差异?

【问题讨论】:

  • 你有没有试过阅读函数的描述?
  • Receive 想把它读取的大小放在某处; send 只需要知道长度,不会修改。

标签: c sockets udp sendto recvfrom


【解决方案1】:

由于 UDP 不是基于连接的(没有你说的 connect(sd, ...) 调用:从现在开始,与套接字描述符 sd 相关的所有数据都将来自一个众所周知的 IP 端口对),每当你发出 @ 987654324@ 它将(尝试)向您返回传入数据的来源地址。

如果地址不为 NULL,则将地址写入 src_addr 缓冲区。该缓冲区由调用者提供,其大小必须通过设置 addr_len 参数来指定。它是通过指针传递的,因为recvfrom() 在使用它来限制写入src_addr 的数据量后,会用实际 地址长度覆盖它。我们可以说 addr_len 是一个输入输出参数。

另一方面,sendto() 的调用者将确切知道目标地址,因此在这种情况下,addr_len 是按值传递的,因为它是一个仅输入参数。

您在问题中链接的指南中清楚地解释了此信息。

【讨论】:

  • 谢谢!我迷失在行话中,因此该指南并不是很有用。所以原因是 actual 地址长度是已知的,因为 UDP 网络不是基于连接的。因此我们通过指针传递,因为这个值是可以修改的。
  • 实际上一个选项可以在 UDP 上调用 connect() 来指定(唯一的)远程地址(但实际上不像 TCP 那样进行通信与 SYN/ACK 交换),然后使用 send() 和 recv() 隐含该地址;见linux.die.net/man/7/udp等。但是 sendto() recvfrom() sendmsg() recvmsg() without connect() 更常用并且按照您的描述工作。
【解决方案2】:

我注意到 recvfrom() 作为最后一个参数需要一个指向 sendto() 时存储服务器地址长度的变量 需要存储客户端地址长度的变量。

你实际上是在回答你自己的问题

recvfrom() as last parameter requires a pointer to
the variable storing the length of server address.


while sendto() requires the variable that stores 
the length of the client address.

recvfrom() 需要指针,因为它将值存储到该指针指向的位置。由于在c 中没有所谓的引用调用,因此您需要传递指针来模拟引用调用行为。

【讨论】:

  • 这基本上是正确的,但请注意,“引用调用”是一个非常笼统/抽象的概念,可以将其视为通过将指针作为函数参数传递来实现在 C 中。因此,可以说“c 支持按引用调用”
  • @Ctx 不,那是错误的。 C 仅支持按值调用。您可以模拟 call-by-ref 传递指针,但这不会使 C 支持它(它不是该语言的本机)。
  • 感谢 Kiran Biradar 的回答并感谢 Jean-Baptise Yunes。为什么 recvfrom 需要指针指向的位置,而 sendto 不需要?
  • @Jean-BaptisteYunès 对这些概念的看法非常狭隘,对于程序员来说很典型。
猜你喜欢
  • 1970-01-01
  • 2021-04-10
  • 2016-04-04
  • 2021-06-07
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 2013-01-04
  • 1970-01-01
相关资源
最近更新 更多