Android 進程通訊套接字LocalSocket

咱們知道,Android上常見的多進程通信有如下幾種:java

AIDL 進程通訊接口

Binder接口

Messenger通訊框架

BroadCastReciever 廣播

ContentObserver/ContentProvider

FileObserver(http://blog.csdn.net/happy_6678/article/details/7095012)

網絡,(http網絡中轉,rpc,dwr,jms,xmpp)

Intent通訊

 

固然,咱們還有另外一種方案服務器

LocalSocket 是Unix進程通訊的基礎網絡

 

認識幾個經常使用的函數:app

客戶端:框架

     LocalSocket客戶端使用,建立套接字socket

     LocalSocketAddress 套接字地址,其實就是文件描述符(主要是服務器的地址,固然也能夠客戶端自個綁定地址)ide

setSoTimeout設置超時函數

connect客戶端主動向服務端請求鏈接ui

服務端:.net

LocalServerSocket服務端使用,建立套接字同時指定文件描述符

accept等待客戶端鏈接(阻塞)

共同:

getInputStream獲取套接字輸入流

getOutputStream獲取套接字輸出流

close關閉套接字,客戶服務都須要

關於套接字的通訊直接就是對java輸入輸出流的操做了,可是有一點很重要:對於套接字獲取的各類輸入或者輸出流,若是調用close函數關閉了對應的流,那麼套接字也會自動關閉了,再次對其獲取輸入輸出流的時候會提示 socket not creat 。這點不一樣於C下socket的 shutdown函數,我也由於這折騰了好久。

下面很少說上代碼,我對在客戶端對其作了小小的封裝:

class ClientConnect {  
    private static final String TAG = "ClientConnect";  
    private static final String name = "com.repackaging.localsocket";  
    private LocalSocket Client = null;  
    private PrintWriter os = null;  
    private BufferedReader is = null;  
    private int timeout = 30000;  
      
    public void connect(){    
        try {  
            Client = new LocalSocket();  
            Client.connect(new LocalSocketAddress(name));  
            Client.setSoTimeout(timeout);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
              
    public void send(String[] data) {  
        try {  
            os = new PrintWriter(Client.getOutputStream());  
            for(int i = 0 ; i < data.length ; i ++){  
                os.println(data[0]);  
            }  
            os.println(FLAG);  
            os.flush();  
            Log.d(TAG,"send");  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
      
    public String recv() {  
        Log.d(TAG,"recv");  
        String result = null;  
        try {  
            is = new BufferedReader(new InputStreamReader(Client.getInputStream()));  
            result = is.readLine();  
            Log.d(TAG, result);  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
        }  
        return result;  
    }  
      
    public void close() {  
        try {  
            is.close();  
            os.close();  
            Client.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}

因爲是在Android代碼上使用,爲了防止ANR,對於服務端,確定是放到線程中去的。對於阻塞模式的客戶端(recv等函數),也必須放在線程中。

服務端線程:

class ServerThread implements Runnable {  
  
    @Override  
    public void run() {  
        LocalServerSocket server = null;  
        BufferedReader mBufferedReader = null;  
        PrintWriter os = null;  
        LocalSocket connect = null;  
        String readString =null;  
        try {  
            server = new LocalServerSocket("com.repackaging.localsocket");        
            while (true) {  
                connect = server.accept();  
                Credentials cre = connect.getPeerCredentials();  
                Log.i(TAG,"accept socket uid:"+cre.getUid());  
                mBufferedReader = new BufferedReader(new InputStreamReader  
                        (connect.getInputStream()));  
                while((readString=mBufferedReader.readLine())!=null){  
                    if(readString.equals("finish")) break;  
                    Log.d(TAG,readString);  
                }  
                os = new PrintWriter(connect.getOutputStream());  
                os.println("allow");  
                os.flush();  
                Log.d(TAG,"send allow");  
            }     
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        finally{  
            try {  
                mBufferedReader.close();  
                os.close();  
                connect.close();  
                server.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
      
}
相關文章
相關標籤/搜索