關於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 {@Overridepublic 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();}}}