Android NDK网络通信篇(五)
本地通信篇
前言
在同一个设备或者同一个APP里面,我们可以通过LocalSocket来实现本地通信,比如可以用Java代码实现一个本地通信的C/S架构的程序,也可以用Java代码实现客户端代码,用原生代码实现服务端代码,本篇重点讲解后一种。
本地socket通信和TCP以及UDP通信的区别在于本地socket通信不需要IP地址和端口号,只需要一个命名空间名称即可。这样我们就可以很方便的在同一个设备的不同应用之间进行通信,是不是很强大?在不同应用之间进行通信,除了使用Messenger和binder,本地socket通信给我们提供了别一种选择。
本地通信相关的头文件
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/endian.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
本地通信函数解析
创建本地socket
int socket(int domain, int type, int protocal);
参数解析:
domain:指定将会产生通讯的socket域,并且选择用到的协议族。android平台目前支持以下协议族:
l PF_LOCAL:主机内部通讯协议族,该协议族使用物理上运行在同一台设备上的应用程序可以使用Socket APIs进行通信。
l PF_INET:IPv4协议族,该协议族使得运行的应用程序可以与网络上的其它应用程序进行通讯。
type:指通信的类型,支持以下两种类型:
SOCK_STREAM:供TCP协议使用。
SOCK_DGRAM:供UDP协议使用。
protocal:指定将会用到的协议。对于大部分协议族和协议类型来说,只能使用一个协议。为了选择默认的协议,该参数可以设为零。
如果socket创建成功,将会返回对应的socket描述符,否则返回-1。
示例代码:
int NewLocalSocket(JNIEnv *env,jobject obj){
int sd=socket(PF_LOCAL,SOCK_STREAM,0);
return sd;
}
绑定本地socket
int bind(int socketDescriptor, const struct sockaddr* address, int addressLength);
参数解析:
socketDescriptor:指服务端socket
address:指socket要绑定的服务端地址结构体
addressLength:指定address结构体的大小
如果绑定成功,返回0,否则返回-1
示例代码:
int BindLocalSocket(JNIEnv *env,jobject obj,int sd,const char *name){
sockaddr_un address;
memset(&address,0, sizeof(address));
address.sun_family=AF_LOCAL;
char *sunPath=address.sun_path;
size_t nameLen=strlen(name);
socklen_t pathLen=nameLen;
pathLen++;
*sunPath++=NULL;
strcpy(sunPath,name);
socklen_t socklen=(offsetof(sockaddr_un,sun_path))+ pathLen;
unlink(address.sun_path);
int result=bind(sd,(sockaddr *)&address,socklen);
return result;
}
监听本地连接
int listen(int socketDescriptor, int backlog);
参数解析:
socketDescriptor:指服务端socket
backlog:指服务端可以接受的最大的连接数,如果连接请求超过这个最大数,超过的请求就会排队。
如果函数调用成功返回0,否则返回-1
示例代码:
int ListenOnSocket(JNIEnv *env,jobject obj,int sd,int backlog){
int result=listen(sd,backlog);