Android中的本地套接字(Local Socket),主要用于进程或者线程间的通信,实现的方式类似于socket,但其实是对Linux中Socket进行了封装,具体的内容可以随便搜一下,有很多相关的教程,这里主要记录下实现的过程中遇到的很多问题。
Java层实现Server:
try {
localServerSocket = new LocalServerSocket( SOCKET_NAME);
while( true) {
Log. v( "sysser", "Java: wait socket connect");
LocalSocket socket = localServerSocket.accept();
Log. v( "sysser", "Java: socket connect success");
while( true) {
bufferedReader = new BufferedReader( new InputStreamReader(socket.getInputStream()));
bufferedReader.read( recv_bytes, 0, 1024);
Log. v( "sysser", "Java: socket recv : "+String. format( "%c", recv_bytes[ 0]+ 0x30));
Thread. sleep( 1000);
printWriter = new PrintWriter(socket.getOutputStream());
printWriter.println(ProtoNum. SEND_OK+ "");
printWriter.flush();
Log. v( "sysser", "Java: socket 1s");
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
localServerSocket = new LocalServerSocket( SOCKET_NAME);
while( true) {
Log. v( "sysser", "Java: wait socket connect");
LocalSocket socket = localServerSocket.accept();
Log. v( "sysser", "Java: socket connect success");
while( true) {
bufferedReader = new BufferedReader( new InputStreamReader(socket.getInputStream()));
bufferedReader.read( recv_bytes, 0, 1024);
Log. v( "sysser", "Java: socket recv : "+String. format( "%c", recv_bytes[ 0]+ 0x30));
Thread. sleep( 1000);
printWriter = new PrintWriter(socket.getOutputStream());
printWriter.println(ProtoNum. SEND_OK+ "");
printWriter.flush();
Log. v( "sysser", "Java: socket 1s");
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
java层没什么好说的,现成的API,即调即用,需要注意
SOCKET_NAME 保持一致即可。
native层实现Client:
在native层实现遇到了一些问题:
1、首先缺少了
cutils/sockets.h,该库在native层并未提供,而是被阉割了,Android源码下可以找到,对应路径为/system/core/include/cutils,以及libcutils,编译好该模块的so和include文件一起添加到你使用的ndk版本对应的路径。此处提供一个大牛整理好的arm的so。如果需要其他架构的so,可以从目标手机中取出或者编译源码重新生成即可。
2、我使用IDE是Android Studio2,.2+NDK-r13,包含了以上的ndk-patch后,仍然报错,提示没有
cutils/sockets.h,具体的原因是因为在生成的时候会将所有架构的so都生成,如果都需要的话那么需要分别修改ndk对应的环境,否则这样,只添加需要的架构。
defaultConfig {
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
}
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
}
3、既然都包含了头文件,so文件也是少不了的,链接相应动态库
LOCAL_LDFLAGS += -llog -lcutils
4、如果之前编译过的,需要清理下工程,删除之前生成的其他架构的文件。
具体实现:
int socket = -
1;
unsigned char socket_buffer[ 1024];
memset(socket_buffer, 0, sizeof(socket_buffer));
while( 1)
{
while(socket < 0)
{
socket = socket_local_client( SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
LOGI( "socket:%d",socket);
sleep( 1);
}
socket_buffer[ 0] = 0x1;
int result = send(socket,( const void *)socket_buffer, sizeof(socket_buffer), 0);
sleep( 1);
result = recv(socket,socket_buffer, sizeof(socket_buffer), 0);
LOGI( "socket:%d",socket_buffer[ 0]);
unsigned char socket_buffer[ 1024];
memset(socket_buffer, 0, sizeof(socket_buffer));
while( 1)
{
while(socket < 0)
{
socket = socket_local_client( SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
LOGI( "socket:%d",socket);
sleep( 1);
}
socket_buffer[ 0] = 0x1;
int result = send(socket,( const void *)socket_buffer, sizeof(socket_buffer), 0);
sleep( 1);
result = recv(socket,socket_buffer, sizeof(socket_buffer), 0);
LOGI( "socket:%d",socket_buffer[ 0]);
}
如有不对之处请提出。
转载请注明出处。