Android 进程通信套接字LocalSocket
博客专区 > IamOkay 的博客 > 博客详情
Android 进程通信套接字LocalSocket
IamOkay 发表于2年前
Android 进程通信套接字LocalSocket
  • 发表于 2年前
  • 阅读 409
  • 收藏 3
  • 点赞 1
  • 评论 4

【腾讯云】新注册用户域名抢购1元起>>>   

摘要: Android Unix-like进程通信套接字LocalSocket

我们知道,Android上常见的多进程通讯有以下几种:

AIDL 进程通信接口

Binder接口

Messenger通信框架

BroadCastReciever 广播

ContentObserver/ContentProvider

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

网络,(http网络中转,rpc,dwr,jms,xmpp)

Intent通信

 

当然,我们还有另一种方案

LocalSocket 是Unix进程通信的基础

 

认识几个常用的函数:

客户端:

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

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

setSoTimeout设置超时

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

服务端:

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();  
            }  
        }  
    }  
      
}

 

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 184
博文 448
码字总数 365335
评论 (4)
554330833a
LocalSocket 和 Socket有什么区别?
IamOkay

引用来自“554330833a”的评论

LocalSocket 和 Socket有什么区别?

LocalSocket 是Unix进程通信套接字,主要用于进程通信,不是网络通信
554330833a

引用来自“IamOkay”的评论

引用来自“554330833a”的评论

LocalSocket 和 Socket有什么区别?

LocalSocket 是Unix进程通信套接字,主要用于进程通信,不是网络通信

哦,原来如此,请问为什么Android上开启ServerSocket后,从Socket中取得的IP地址是0.0.0.0的呢?有4G网络
IamOkay

引用来自“554330833a”的评论

引用来自“IamOkay”的评论

引用来自“554330833a”的评论

LocalSocket 和 Socket有什么区别?

LocalSocket 是Unix进程通信套接字,主要用于进程通信,不是网络通信

哦,原来如此,请问为什么Android上开启ServerSocket后,从Socket中取得的IP地址是0.0.0.0的呢?有4G网络
没注意过,改天试试
×
IamOkay
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: