2011-07-25 29 views
3

我无法理解有关Unix域套接字的bind()函数。C编程 - 了解绑定()

address.sun_family = AF_UNIX; 
addrlen = sizeof(address.sun_family) + strlen(SOCK_PATH); 
. 
. 
. 
bind(socket_fd, (struct sockaddr *) &address, addrlen) != 0) 

正如我现在明白了,这需要的是与插座()创建的socket_fd(位于进程命名空间),和“适用”,载于地址插座上的地址信息。基本上创建它,以便其他进程可以使用它....我认为这是正确的。

我不明白的是需要addrlen参数。这是没有前导/尾随空字节的地址结构的长度。正确?这个参数是否需要告诉bind()要读出多少字节的地址?

感谢您的洞察!

回答

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中预计

+0

好的..但我需要&addrlen作为不可避免的accept()函数的第三个参数。那么为什么我不能在bind()和accept()中使用它? –

+0

值是相同的(所以可以设置它),但是无论如何设置它都是无效的(正确地完成,它是'addrlen = sizeof(struct sockaddr_un);'只要你使用相同的套接字结构) – KevinDTimm

+0

在'accept'的情况下,addrlen既是输入也是输出 - 你指定你传入的缓冲区的大小,内核告诉你连接到你的sockaddr有多大。 –

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变元指定该结构的尺寸为的尺寸为,因为可以传递不同类型的结构(不同尺寸)。例如,struct sockaddr_un*,struct sockaddr_in*。一个“普通”结构被传递,struct sockaddr*,因此bind不知道什么是实际您的结构的类型。这就是为什么你必须通过这个长度。

PS:我确定你的意思是进程地址空间而不是进程名字空间

0

我还在学习,那是什么把我带到这里,所以也许解释我的理解也会帮助我学习,所以要疲倦,我可能是非常错误的,或者我可能会在正确的方向...

你需要它,因为IPv4和IPv6地址是不同的长度,就像不同协议的地址一样,我假设并不是所有的协议,如Apple Talk或火腿无线电协议都使用类似于IPv4样式地址的地址,这些地址是一组4个字节,八位字节,我认为它们被调用,用“。”分隔。所以当你调用“sizeof(struct sockaddr_in)”时,你传递的是一个“int”,它是sockaddr_in包含的字节数,它与sizeof(struct sockaddr_in)的“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()”会返回你需要的int值,这就是第三个参数的参数。