我无法理解有关Unix域套接字的bind()函数。
address.sun_family = AF_UNIX;
addrlen = sizeof(address.sun_family) + strlen(SOCK_PATH);
.
.
.
bind(socket_fd, (struct sockaddr *) &address, addrlen) != 0)
据我所知,这需要使用socket()创建的socket_fd(位于进程名称空间中),并将地址中包含的地址信息“应用”到套接字。基本上创建它以便其他进程可以使用它....我认为这是正确的。
我不明白需要addrlen参数。这是没有前导/尾随空字节的地址结构的长度。正确?这个参数是否必须告诉bind()从地址读出多少字节?
感谢您的见解!
答案 0 :(得分:2)
简单地说,绑定说到系统:okay, from now on, any packet with destination {address->sun_addr} should be forwarded to my socket_fd, so I can read them
。
addrlen
参数指定结构的 size ,因为可以传递不同类型的结构(不同大小)。例如,struct sockaddr_un*
,struct sockaddr_in*
。相反,传递了“常见”结构struct sockaddr*
,因此bind
不知道您的结构的真实类型是什么。这就是你必须通过长度的原因。
PS:我确定你的意思是进程地址空间而不是进程名称空间。
答案 1 :(得分:1)
不确定为什么你的addrlen设置如下,正确/通常的方法是:
memset(&addr, 0, sizeof(struct sockaddr_un));
/* Clear structure */
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, MY_SOCK_PATH,
sizeof(addr.sun_path) - 1);
if (bind(sfd, (struct sockaddr *) &addr,
sizeof(struct sockaddr_un)) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
注意使用sizeof(),没有预期的strlen / addrlen
答案 2 :(得分:0)
我还在学习,这就是把我带到这里的原因,所以也许解释我的理解也会帮助我学习,所以要疲倦,我可能会非常错,或者我可能会朝着正确的方向前进......
您需要它,因为IPv4和IPv6地址的长度与不同协议的地址不同,我假设并非所有协议(如Apple Talk或Ham Radio协议)都使用类似IPv4样式地址的地址,这些地址是一组4字节,八位字节我认为它们被调用,用“。”分隔。
所以当你调用“sizeof(struct sockaddr_in)”时你传入的是一个“int”,即sockaddr_in所包含的字节数,这与sizeof(struct sockaddr_un)的“sizeof(struct sockaddr_in6)”不同。 sockaddr_in用于inet或IPv4,* _in6用于inet6或IPv6,* _un用于Unix域套接字。我相信Unix域套接字地址是只能用于本地进程通信的文件路径。因此,对于一个,函数/方法需要知道套接字文件的位置,例如/ home / user / Pictures / socket,这样它就可以将它绑定到本地端口,因此strncopy和sun_path业务。这也适用于inet / 6插座,winsocks可能不同。 (在Windows上学习C / C ++最接近我曾经遭遇的自杀)。
通过“sizeof(struct sockaddr_un)”传递的int可用于确定实际实现代码中的执行模式。如果arg [2] = N这样做;否则如果arg [2] = M那样做???可能......
如果您阅读了有关套接字的手册,您会看到该示例使用“sizeof()”而不是addrlen。
注意: 当达到协议地址结构的字节大小时,如果你使用的结构实际上包含有用数据并不重要,你只需要它的大小,这就是使用“sizeof()”在结构中实例化结构的原因。在新创建的struct上返回您需要的int,这是用作第3个参数的参数。