socket进程通信命名方式有两种:1、普通命名空间 2、抽象命名空间
1、普通命名空间:
socket会根据此命名创建一个同名的socket文件,客户端连接的时候读取该socket文件链接到socket 服务端。
此命名空间却又如下3个问题
问题1:
这种方式的弊端是服务必须对socket文件的路径具备写权限,客户端必须知道socket文件路径, 且必 须对读路径有读权限。
问题2:
bind之后,会在文件系统中留下一个文件,然后再close,此文件却不会自动消失,这就导致下 一次会失 败,所以AF_UNIX域socket的bind通常有个unlink()凑热闹。
问题3:
这个文件很容易被其他程序不经意中删除,这导致很奇怪的问题,而很难发现。
2、抽象命名空间:
这种方式不需要创建socket文件,只需要命名一个全局名字,即可让客户端根据此名字进行链接,此 方式中对结构成员sun_path数组赋值时,必须把第一个字节置0,即sun_path[0]=0。简单的说,即时linux 在内村中维护了一个虚拟的“文件系统”。这个文件在close之后会自动消失,并且文件系统中看不到bind的 socket文件,在linux下用命令:netstat -an却有记录。
注意:sun_path[0]='\0'(需字符)。同时在使用这个地址时,必须在anddresslen参数中指定正确的长 度,这个长度是sizeof(sun_family)+strlen(path)。其中path不包含后面的'\0',linux也不会去寻找这个零 字符。
当接收accept()/recvfrom()数据时,linux也不会在sun_path后面附上一个'\0',所以必须根据返回的长 度谨 慎地处理字符串。
第一种方式:
server_addr.sun_family=AF_UNIX;
strcpy(server_addr.sun_path,server_name);
server_len=sizeof(struct sockaddr_un);
client_len=server_len;
第二种方式:
server_addr.sun_family=AF_UNIX;
strcpy(server_addr.sun_path,server_name);
server_addr.sun_path[0]=0;
server_len=strlen(server_name)+offsetof(struct sockaddr_un,sun_path);
其中offsetof()函数在#include<stddef.h>头文件中定义。因第二种方式的首字节置0,我们可以在命名字符串server_name前添加一个占位字符串,例如:
#define server_name "@socket_server"
注意:命名空间
NAMESPACE_RESERVED :就是init.c中/dev/socket/下建立的socket文件。
NAMESPACE_FILESYSTEM:普通命名空间
NAMESPACE_ABSTRACT:虚拟命名空间