记一次 Android 关于 Unix abstract socket 的连接问题
資深大佬 : howellz 6
Keywords
Android Unix abstract namespace socket LocalSocket LocalServerSocket length 地址长度
正文
在一个项目中,需要 native 的程序对 java 的LocalServerSocket发起连接。即 Java 端监听某个 Unix 套接字,等待 native 的程序连接。结果死活连不上,总是提示Connection Refused(110)。
这是 Java 端的代码示意,非常简单:
public void listen() { String name = "myname"; mSocket = new LocalServerSocket(name); LocalSocket client = mSocket.accept(); ... }
发现客户端如果用 java 代码连接很容易就连接上了:
public void connect() { String name = "myname"; LocalSocket client = new LocalSocket(); client.connect(new LocalSocketAddress(name)); Log.d("client", "connected to " + name); }
但是客户端如果使用如下的 c 代码就连接不上:
#define SOKET_NAME "@myname" void connect() { char* name = SOKET_NAME; struct sockaddr_un addr; int sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) { perror("failed to create socket"); return -1; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOKET_NAME, sizeof(addr.sun_path)-1); if (name[0] == '@') addr.sun_path[0] = ' '; if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("failed to connect"); close(sock); return -1; } ... }
这段代码主要参考权威 man UNIX(7): https://man7.org/linux/man-pages/man7/unix.7.html
注意,这个 SOCKET_NAME 中的第一个字符 @是一个占位符,其实后面被’