http://blog.chinaunix.net/uid-20364597-id-3794822.html
比如说我们的硬件上跑着Android,但又需要有另一个程序来处理一些事情(此程序也运行在同一台机器上)。简单地说,就是两个独立的进程之间进行通信,那socket是最好不过了,一般的,在Linux环境下,如果是两个单独的C程序通信的话,一个做服务器,另一个做客户端,可以在/tmp目录下创建一个socket文件节点,通过这个节点来通信,例如,客户端可以这样来写:
#define SOCKET_PATH "/tmp/mysocket"
struct sockaddr_un address;
int len,result;
int server_fd;
server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
address.sun_family = AF_UNIX;
strcpy(address.sun_path, SOCKET_PATH);
len = sizeof(address);
result = connect(server_fd, (struct sockaddr *)&address, len);
if(result == -1) {
printf("Connect fail\n");
close(server_fd);
server_fd = 0;
return -1;
}
这是两个C程序通信的方式,但在Android下怎么办呢?假如在Android端通过Java实现服务器,另一个C程序端实现客户端,应该怎么实现呢?有人可能会想到在Android端把消息发到Native层,再由Native层发送出去,这样就又变成了两个C程序的通信了,但是Java与Native之间的通信又得自己去实现了,这样不是很麻烦么。
好了,来看一下Android的LocalServerSocket类,此类会创建一个本地socket,但这个socket并不像在C下面一样会显示在文件系统中:
ss = new LocalServerSocket("my.socket");
服务器端创建好了,socket节点名也知道了,但在C端怎么连接上呢,在C程序当中如果无法发现节点文件,那调用connect肯定会失败,这里到底应该怎么办呢? 直接来看代码吧(注意红色标记部分):
#define SOCKET_PATH "/tmp/mysocket"
int sockfd = -1;
int addrlen = 0;
struct sockaddr_un addr;
sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
if (sockfd < 0) {
fprintf(stderr, "Can not create socket for twin!\n");
return -1;
}
bzero(&addr, sizeof(addr));
strcpy(&addr.sun_path[1], SOCKET_PATH);
addr.sun_family = AF_UNIX;
addrlen = 1 + strlen(SOCKET_PATH) + sizeof(addr.sun_family);
if (connect(sockfd, (struct sockaddr *)&addr, addrlen) < 0) {
fprintf(stderr, "Can not connect server!\n");
close(sockfd);
return -1;
}
如果要与Android的LocalServerSocket类创建的socket进行通信,只需要在socket节点名前加个'\x00'即可,原因是LocalServerSocket类底层的代码是这样创建socket的,所以客户端必须这样的去连接,否则系统会认为是不同的socket.这就是android中所谓的abstract namespace。