C编程-理解bind()

C编程-理解bind(),c,sockets,unix,dns,theory,C,Sockets,Unix,Dns,Theory,我很难理解与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(位于进程名称空间中),并将address中包含的地址信息“

我很难理解与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(位于进程名称空间中),并将address中包含的地址信息“应用”到套接字。本质上是创建它以便其他进程可以使用它。。。。我认为这是正确的

我不明白的是,有必要提出addrlen论点。这是不带前导/尾随空字节的地址结构的长度。对的这个参数是否有必要告诉bind()从地址中读取多少字节


谢谢你的洞察力

不确定为什么您的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期望简单地说,bind对系统说:
好的,从现在开始,任何目的地为{address->sun\u addr}的数据包都应该转发到我的socket\u fd,这样我就可以读取它们了

addrlen
参数指定结构的大小,因为可以传递不同类型的结构(大小不同)。例如,
struct sockaddr\u un*
struct sockaddr\u in*
。而是传递一个“公共”结构,
struct sockaddr*
,因此
bind
不知道结构的真正类型。这就是为什么你必须通过长度


PS:我肯定你指的是进程地址空间,而不是进程名称空间。

我还在学习,这就是我来到这里的原因,也许解释我的理解也会帮助我学习,所以请注意,我可能大错特错,或者我的方向是正确的

您需要它,因为IPv4和IPv6地址的长度不同,不同协议的地址也不同。我假设并非所有协议(如Apple Talk或Ham无线电协议)都使用类似IPv4风格的地址,这是一组4字节的地址,我认为它们被称为八位字节,以“.”分隔

因此,当您调用“sizeof(struct sockaddr_in)”时,您传递的是一个“int”,它是sockaddr_in包含的字节数,这与sizeof(struct sockaddr_un)的“sizeof(struct sockaddr_in 6)”不同。sockaddr\u in代表inet或IPv4,*\u in6代表inet 6或IPv6,*\u 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()实例化结构的原因在新创建的结构上,返回所需的int,这就是用作第三个参数的参数的int。

OK。。但是我需要&addrlen作为不可避免的accept()函数的第三个参数。那么为什么我不在bind()和accept()中使用它呢?值是相同的(所以设置它是可以的),但是不管如何,您都设置它无效(正确完成,只要使用相同的套接字结构,
accept
,它就是
addrlen=sizeof(struct sockaddr\u un);
,addrlen既是一个输入又是一个输出——您指定要传入的缓冲区的大小,内核会告诉您连接到您的sockaddr有多大。好的,struct sockaddr_un的大小是110。sockaddr_un.sun_族为1(+一个空字节)=2,sockaddr_un.sun_路径为107(+一个空字节)=108。2 + 108 = 110. 正确吗???正如我在上面编码的一样,使用sizeof()-不要做任何其他事情,因为你会对元素对齐等事情感到不快的惊讶(另外,请参见下面Cicada的答案)