c - recvfrom() 中的 addrlen 字段是做什么用的?

标签 c sockets udp recv

我在我的程序中使用 recvfrom 从我在 src_addr 中指定的服务器获取 DGRAM 数据。但是,我不确定为什么需要初始化并传入 addrlen。

我阅读了手册页,但我并没有真正理解它的含义。

If src_addr is not NULL, and the underlying protocol provides the source address, this source address is filled in. When src_addr is NULL, nothing is filled in; in this case, addrlen is not used, and should also be NULL. The argument addrlen is a value-result argument, which the caller should initialize before the call to the size of the buffer associated with src_addr, and modified on return to indicate the actual size of the source address. The returned address is truncated if the buffer provided is too small; in this case, addrlen will return a value greater than was supplied to the call.

我猜这与 src_addr 是 ipv4 或 ipv6 有关。这是正确的吗?

谢谢!

最佳答案

也许您的理解有误。谈:

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, 
                 struct sockaddr *src_addr, socklen_t *addrlen);

src_addr不是用来交in你想收听的地址,而是你提供的一个存储位置得到实际的源地址 out

因此,如果您将 src_addr 设置为 NULL,因为您根本对地址不感兴趣,您不必关心 addrlen 因为它不会被使用无论如何。

另一方面,如果你想知道源地址,你不仅要提供一个存储位置,还要告诉你提供的存储位置有多大。 这就是为什么你应该将 *addr_len 初始化为你分配的缓冲区大小。

在您调用后,addrlen 指向的值将通知您分配用于存储源地址的空间中有多少(如果有)实际填充了数据。

关于尺寸

struct sockaddr 和来回传递大小的整个麻烦与这样一个事实有关,即使它们在网络套接字中使用得最多,但其意图是更笼统的概念。

以 unix 域套接字为例,因为它们是通过文件系统实现的,它们需要一个与基于 IP 的网络已知的完全不同的寻址方案。这里使用的 sockaddr 的类型是:

struct sockaddr_un {
  sa_family_t sun_family;               /* AF_UNIX */
  sun_path[UNIX_PATH_MAX];  /* pathname */
};

将此与基于 IP 的网络中使用的结构进行比较:

struct sockaddr_in {
  sa_family_t    sin_family; /* address family: AF_INET */
  in_port_t      sin_port;   /* port in network byte order */
  struct in_addr sin_addr;   /* internet address */
};

应该清楚两者没有太多共同点。

socket 的设计能够适应这两种情况。

关于c - recvfrom() 中的 addrlen 字段是做什么用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15168095/

相关文章:

c - Linux:将 UDP 监听套接字绑定(bind)到特定接口(interface)(或找出数据报来自的接口(interface))?

c - 优化选择排序?

c - 查找数组中给定字符串的索引

flutter - 如何连接 asBroadcastStream 以便可以在流构建器中使用它?

c - 在 Linux 上使用套接字发出 https 请求

Java DatagramSocket(UDP Socket)仅在先前已发送数据包时接收

c - 指针是否在线程之间共享?

C——指针+1的含义

php通过socket编程传递c结构数据

encryption - 加密传输有哪些选项