也许您这边有误解。谈论:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
src_addr
is not习惯于手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 */
};
很明显,两者没有太多共同点。
插座的设计能够适合这两种情况。