关于Android应用与Framework的socket通信,相信关心这个问题的朋友们已经看过《android使用socket使底层和framework通信》这篇文章,美中不足的是作者只贴出一些关键的代码片段而并没有放出源码。我这里还是以一个能实际运行的例子为基础来讲,这样也方便大家学习。
首先看一下效果,如下图。我填写姓名"Potter",选择性别"Mr"然后点击发送,底层socket收到消息后将消息直接返回给我,我将返回的结果(Mr.Potter)直接显示在Result。
#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(); } } }