也许您的身边有误解。谈论:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
src_addr
不是用来交你想听的地址,而是你提供的一个存储位置,用来获取实际交出的源地址。
因此,如果您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 */
};
应该清楚两者没有太多共同点。
插座的设计能够适应这两种情况。