本文尝试使用UNIX套接字来实现内核模块与用户空间的通信,内核模块作为客户端,用户空间程序作为服务器。
我注意到UNIX套接字有三种类型的地址(参考“man 7 unix”)。
当我使用路径名类型地址时,它工作正常。但是当我使用抽象类型地址时,内核模块无法连接到服务器。它返回-ECONNREFUSED。
我的代码有什么问题吗?
内核代码
struct sockaddr_un s_addr;
ret = sock_create_kern(&init_net, AF_LOCAL, SOCK_STREAM, 0, &cl_sock);
if (ret < 0) {
/*...*/
}
memset(&s_addr, 0, sizeof(struct sockaddr_un));
s_addr.sun_family = AF_LOCAL;
s_addr.sun_path[0] = 0;
strncpy(s_addr.sun_path + 1, "my_test", sizeof(s_addr.sun_path) - 1);
ret = cl_sock->ops->connect(cl_sock, (struct sockaddr *)&s_addr, sizeof(s_addr), 0);
if (ret < 0) {
/*...*/
}
服务端代码
server_socket = socket_local_server("my_test", ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
if (server_socket < 0) {
/*...*/
}
accept(server_socket , NULL, NULL);
我希望使用抽象类型地址连接到服务器。
1条答案
按热度按时间cotxawn71#
试试这个:
在抽象名称空间中,必须计算 sun_path 中地址的确切长度,作为 sockaddr 大小的一部分。您想要的地址是
"\0my_test"
,但您传入了完整的sizeof(s_addr)
,这意味着指定的地址类似于"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."
-不同的套接字。(By相反,路径名本地套接字被理解为具有终止空字节。
"/tmp/my_test\0"
和"/tmp/my_test\0\0\0\0..."
都引用套接字文件/tmp/my_test
。Linux man page for unix sockets在处理AF_UNIX地址格式时解决了这个问题,尽管可能不像匆忙的程序员希望的那样清楚。