我们都知道intent是Android各组件之间通信的核心。对于简单的的进程内或进程间通信,intent基本能够满足了。但是一些稍微复杂些的交互(如一些随时需要的控制请求)等,仅仅依靠intent这种消息机制实现便显得力不从心了。关于Android进程间的通信,大家普遍用的还是AIDL,但它只适用于 Activity与Service之间的通信,不免有一定的限制。而我这次主要介绍的是LocalSocket。

之前关于套接字的操作都是在C上使用的,虽然java封装了很多细节,但用起来不免有些不习惯。C虽然繁琐却使得开发者更为了解其具体细节。而本文也旨在记录自己毕设中用到技术或碰到的问题,以java角度出发。先看看TCP socket通信的模型,LocalSocket也一样只不过是没有跨越网络边界:

android DatagramSocket receive 超时_套接字

认识几个常用的函数:

客户端:

LocalSocket客户端使用,创建套接字

LocalSocketAddress 套接字地址,其实就是文件描述符(主要是服务器的地址,当然也可以客户端自个绑定地址)

setSoTimeout设置超时

connect客户端主动向服务端请求连接

服务端:

LocalServerSocket服务端使用,创建套接字同时指定文件描述符

accept等待客户端连接(阻塞)

共同:

getInputStream获取套接字输入流

getOutputStream获取套接字输出流

close关闭套接字,客户服务都需要

关于套接字的通信直接就是对java输入输出流的操作了,但是有一点很重要:对于套接字获取的各种输入或者输出流,如果调用close函数关闭了对应的流,那么套接字也会自动关闭了,再次对其获取输入输出流的时候会提示 socket not creat 。这点不同于C下socket的 shutdown函数,我也因为这折腾了很久。

下面不多说上代码,我对在客户端对其做了小小的封装:



    1. class ClientConnect {  
    2. private static final String TAG = "ClientConnect";  
    3. private static final String name = "com.repackaging.localsocket";  
    4. private LocalSocket Client = null;  
    5. private PrintWriter os = null;  
    6. private BufferedReader is = null;  
    7. private int timeout = 30000;  
    8.       
    9. public void connect(){    
    10. try {  
    11. new LocalSocket();  
    12. new LocalSocketAddress(name));  
    13.             Client.setSoTimeout(timeout);  
    14. catch (IOException e) {  
    15.             e.printStackTrace();  
    16.         }  
    17.     }  
    18.               
    19. public void send(String[] data) {  
    20. try {  
    21. new PrintWriter(Client.getOutputStream());  
    22. for(int i = 0 ; i < data.length ; i ++){  
    23. 0]);  
    24.             }  
    25.             os.println(FLAG);  
    26.             os.flush();  
    27. "send");  
    28. catch (IOException e) {  
    29.             e.printStackTrace();  
    30.         }  
    31.     }  
    32.       
    33. public String recv() {  
    34. "recv");  
    35. null;  
    36. try {  
    37. new BufferedReader(new InputStreamReader(Client.getInputStream()));  
    38.             result = is.readLine();  
    39.             Log.d(TAG, result);  
    40. catch (IOException e) {  
    41.             e.printStackTrace();  
    42. finally {  
    43.         }  
    44. return result;  
    45.     }  
    46.       
    47. public void close() {  
    48. try {  
    49.             is.close();  
    50.             os.close();  
    51.             Client.close();  
    52. catch (IOException e) {  
    53.             e.printStackTrace();  
    54.         }  
    55.     }  
    56. }


    调用代码:




      1. ClientConnect client = new ClientConnect();  
      2.         client.connect();  
      3.         client.send(data);  
      4.         result = client.recv();  
      5.         client.close();


      由于是在Android代码上使用,为了防止ANR,对于服务端,肯定是放到线程中去的。对于阻塞模式的客户端(recv等函数),也必须放在线程中。

      服务端线程:


        1. class ServerThread implements Runnable {  
        2.   
        3. @Override  
        4. public void run() {  
        5. null;  
        6. null;  
        7. null;  
        8. null;  
        9. null;  
        10. try {  
        11. new LocalServerSocket("com.repackaging.localsocket");        
        12. while (true) {  
        13.                 connect = server.accept();  
        14.                 Credentials cre = connect.getPeerCredentials();  
        15. "accept socket uid:"+cre.getUid());  
        16. new BufferedReader(new InputStreamReader  
        17.                         (connect.getInputStream()));  
        18. while((readString=mBufferedReader.readLine())!=null){  
        19. if(readString.equals("finish")) break;  
        20.                     Log.d(TAG,readString);  
        21.                 }  
        22. new PrintWriter(connect.getOutputStream());  
        23. "allow");  
        24.                 os.flush();  
        25. "send allow");  
        26.             }     
        27. catch (IOException e) {  
        28.             e.printStackTrace();  
        29.         }  
        30. finally{  
        31. try {  
        32.                 mBufferedReader.close();  
        33.                 os.close();  
        34.                 connect.close();  
        35.                 server.close();  
        36. catch (IOException e) {  
        37.                 e.printStackTrace();  
        38.             }  
        39.         }  
        40.     }  
        41.       
        42. }

        以上就是简单的LocalSocket模型。在处理交互方面还是很方便的,尽量都放到线程中去执行。