Cau*_*tic 2 c sockets udp recv
我在我的程序中使用recvfrom从我在src_addr中指定的服务器获取DGRAM数据.但是,我不确定为什么我需要初始化并传入addrlen.
我阅读了手册页,但我并不真正了解它的内容.
如果src_addr不为NULL,并且底层协议提供源地址,则填写此源地址.当src_addr为NULL时,不会填充任何内容; 在这种情况下,不使用addrlen,也应该为NULL.参数addrlen是一个value-result参数,调用者应该在调用与src_addr关联的缓冲区大小之前初始化,并在返回时修改以指示源地址的实际大小.如果提供的缓冲区太小,则截断返回的地址; 在这种情况下,addrlen将返回一个大于提供给调用的值.
我猜这与src_addr是ipv4或ipv6有关.它是否正确?
谢谢!
也许你身边有一个错误的解释.谈论:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
Run Code Online (Sandbox Code Playgroud)
src_addr是不是用的手在你想听听ADRESS,而是你所提供的存储位置,以获得实际的源地址递出来.
因此,如果你设置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 */
};
Run Code Online (Sandbox Code Playgroud)
将此与基于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 */
};
Run Code Online (Sandbox Code Playgroud)
应该清楚两者没有太多共同之处.
插座设计为能够适应两种情况.