关于Android应用与Framework的socket通信,相信关心这个问题的朋友们已经看过《android使用socket使底层和framework通信》这篇文章,美中不足的是作者只贴出一些关键的代码片段而并没有放出源码。我这里还是以一个能实际运行的例子为基础来讲,这样也方便大家学习。
首先看一下效果,如下图。我填写姓名"Potter",选择性别"Mr"然后点击发送,底层socket收到消息后将消息直接返回给我,我将返回的结果(Mr.Potter)直接显示在Result。
编写socket服务端代码,生成可执行脚本htfsk。
#define SOCKET_NAME "htfsk" #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <sys/un.h> #include <cutils/sockets.h> #include <utils/Log.h> #include <android/log.h> int main(){ char log[200]; int connect_number = 6; int fdListen = -1, new_fd = -1; int ret; struct sockaddr_un peeraddr; socklen_t socklen = sizeof (peeraddr); int numbytes ; char buff[256]; //这一步很关键,就是获取init.rc中配置的名为 "htfsk" 的socket fdListen = android_get_control_socket(SOCKET_NAME); if (fdListen < 0) { sprintf(log,"Failed to get socket '" SOCKET_NAME "' errno:%d", errno); __android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI",log); exit(-1); } //开始监听 ret = listen(fdListen, connect_number); sprintf(log,"Listen result %d",ret); __android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI",log); if (ret < 0) { perror("listen"); exit(-1); } //等待Socket客户端发启连接请求 new_fd = accept(fdListen, (struct sockaddr *) &peeraddr, &socklen); sprintf(log,"Accept_fd %d",new_fd); __android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI",log); if (new_fd < 0 ) { sprintf(log,"%d",errno); __android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI",log); perror("accept error"); exit(-1); } while(1){ //循环等待Socket客户端发来消息 __android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI","Waiting for receive"); if((numbytes = recv(new_fd,buff,sizeof(buff),0))==-1){ sprintf(log,"%d",errno); __android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI",log); perror("recv"); continue; } //发送消息回执给Socket客户端 if(send(new_fd,buff,strlen(buff),0)==-1) { perror("send"); close(new_fd); exit(0); } } close(new_fd); close(fdListen); return 0; }
3、编写客户端java代码。核心代码如下:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.util.Log; /** * Socket客户端 * * @author lai_zs * @date:2012-3-17 下午12:15:09 */ public class SocketClient { private final String SOCKET_NAME = "htfsk"; private LocalSocket client; private LocalSocketAddress address; private boolean isConnected = false; private int connetTime = 1; public SocketClient() { client = new LocalSocket(); address = new LocalSocketAddress(SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED); new ConnectSocketThread().start(); } /** * 发送消息 * @param msg * @return 返回Socket服务端的消息回执 */ public String sendMsg(String msg) { if (!isConnected) { return "Connect fail"; } try { BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); PrintWriter out = new PrintWriter(client.getOutputStream()); out.println(msg); out.flush(); return in.readLine(); } catch (IOException e) { e.printStackTrace(); } return "Nothing return"; } /** * 异步连接Socket,如果连接不上会尝试重复连接十次 * * @author Administrator * */ private class ConnectSocketThread extends Thread { @Override public void run() { while (!isConnected && connetTime <= 10) { try { sleep(1000); Log.i("SocketClient","Try to connect socket;ConnectTime:"+connetTime); client.connect(address); isConnected = true; } catch (Exception e) { connetTime++; isConnected = false; Log.i("SocketClient","Connect fail"); } } } } /** * 关闭Socket */ public void closeSocket() { try { client.close(); } catch (IOException e) { e.printStackTrace(); } } }