安卓IPC機(jī)制之LocalSocket

LocalSocket作為安卓提供的一種IPC機(jī)制,可能應(yīng)用層的同學(xué)比較陌生检诗,我實(shí)際也是在這段時(shí)間做項(xiàng)目使用到才注意到它并去了解的。不過(guò)實(shí)際上framework層里面被頻繁使用到了逢慌,例如我很久前寫的博客從源碼看安卓應(yīng)用的啟動(dòng)過(guò)程里面提到其他進(jìn)程和Zygote進(jìn)程之間的通信使用的是LocalSocket。

那么LocalSocket和Socket到底有什么不同呢涕癣?官方文檔里面其實(shí)提到了它其實(shí)是基于UNIX-domain socket的:

Non-standard class for creating an inbound UNIX-domain socket in the Linux abstract namespace.

Socket本來(lái)是用來(lái)做不同主機(jī)間的網(wǎng)絡(luò)通信的,如果有人想拿來(lái)做本機(jī)的IPC通信就會(huì)發(fā)現(xiàn)它的性能堪憂(例如實(shí)現(xiàn)binder機(jī)制做不到的傳輸大文件)距潘,因?yàn)樗枰呔W(wǎng)絡(luò)協(xié)議棧只搁、打包拆包、計(jì)算校驗(yàn)等氢惋,如果是TCP還需要走三次握手和應(yīng)答。

于是后面就發(fā)展出了UNIX-domain socket (LocalSocket)骚亿,它的api和socket的基本一致熊赖,但是本質(zhì)上只是一種IPC通信,不可和外部主機(jī)通信震鹉,但是因?yàn)镮PC通信是可靠通信,直接將數(shù)據(jù)拷貝到目標(biāo)進(jìn)程內(nèi)存即可传趾,所以沒(méi)有之前說(shuō)的那些耗時(shí)的操作。

使用方式

我們先來(lái)看看它的使用方式:

private void demoClient() throws IOException {
    LocalSocket client = new LocalSocket();
    client.connect(new LocalSocketAddress("me.linjw.localsocket"));
    client.getOutputStream().write(123);
    int read = client.getInputStream().read();
    Log.d(TAG, "response from server : " + read);
    client.close();
}

private void demoServer() throws IOException {
    LocalServerSocket server = new LocalServerSocket("me.linjw.localsocket");
    LocalSocket client = server.accept();
    int read = client.getInputStream().read();
    Log.d(TAG, "request from client :" + read);
    client.getOutputStream().write(read + 1);
    client.getOutputStream().flush();
    client.close();
}

// 打印
// request from client :123
// response from server : 124

沒(méi)錯(cuò)磕仅,看起來(lái)和普通Socket的用法很類似了镊讼。

性能

性能是評(píng)判一種ipc進(jìn)制好壞的重要指標(biāo),例如我們常用的Binder機(jī)制就是用了mmap機(jī)制實(shí)現(xiàn)了數(shù)據(jù)的一次拷貝提高了傳輸速度卸亮。

于是我寫了一個(gè)測(cè)試程序來(lái)對(duì)比AIDL玩裙、LocalSocket和TCP Socket的傳輸速度。測(cè)試的邏輯大概是:

  1. 每次傳輸讀或者寫1024 byte數(shù)據(jù)
  2. 計(jì)算3000次讀或者寫的耗時(shí)(也就是計(jì)算讀3000k或者寫3000k數(shù)據(jù)的總耗時(shí))
  3. LocalSocket和TCP Socket每次傳輸完數(shù)據(jù)都斷開連接,下次需要重新連接

在我們的產(chǎn)品設(shè)備上得到的實(shí)際數(shù)據(jù)如下:

方式 方向 第一次3000k 第二次3000k 第三次3000k 第四次3000k 平均時(shí)間
AIDL 1.711s 1.195s 1.25s 1.169s 1.33125s
LocalSocket 1.674s 1.286s 1.185s 1.219s 1.341s
TCP Socket 10.188s 8.926s 8.865s 8.803s 9.1955s
AIDL 1.261s 1.212s 1.175s 1.23s 1.2195s
LocalSocket 1.387s 1.323s 1.23s 1.35s 1.3225s
TCP Socket 8.284s 8.242s 8.324s 8.285s 8.28375s

從上面的數(shù)據(jù)可以看出來(lái)LocalSocket雖然會(huì)比AIDL慢但是也差的不多溶诞,而tcp的耗時(shí)就比較多了决侈。雖然我沒(méi)有具體看過(guò)LocalSocket的底層原理,但是想來(lái)既然它在framework層被頻繁使用,那么谷歌應(yīng)該也應(yīng)該會(huì)考慮到性能這一點(diǎn)功茴。

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  1. 可以進(jìn)行數(shù)據(jù)流讀寫,沒(méi)有大小限制
  2. 比TCP Socket會(huì)更加安全孽亲,因?yàn)椴荒芡ㄟ^(guò)抓包監(jiān)聽(tīng)傳輸?shù)臄?shù)據(jù)
  3. 不會(huì)開啟線程池(Zygote之所以使用它而不是Binder也是因?yàn)锽inder機(jī)制默認(rèn)會(huì)啟動(dòng)線程池,而fork在多線程下只會(huì)fork出當(dāng)前線程)

缺點(diǎn):

  1. 比Binder的速度還是會(huì)稍微慢那么一點(diǎn)點(diǎn)
  2. 沒(méi)有像AIDL這樣的高層封裝玲昧,需要自己實(shí)現(xiàn)
  3. 和TCP Socket對(duì)比起來(lái)不能跨主機(jī)通信

需要注意的地方

  1. 雖然不是真正的網(wǎng)絡(luò)傳輸,但是也需要聲明android.permission.INTERNET權(quán)限孵延,要不然同樣會(huì)報(bào)java.net.SocketException: Permission denied異常
  2. 雖然可以通過(guò)LocalSocket和framework層直接通信亲配,但是如果系統(tǒng)打開了SeLinux就會(huì)出現(xiàn)Permission denied異常
  3. 在模擬器上LocalSocket的flush用多了耗時(shí)有時(shí)候會(huì)比較嚴(yán)重(Tcp沒(méi)有問(wèn)題,實(shí)機(jī)測(cè)試LocalSocket也沒(méi)有出現(xiàn)問(wèn)題弃榨,猜測(cè)和系統(tǒng)相關(guān))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鲸睛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子官辈,更是在濱河造成了極大的恐慌,老刑警劉巖拳亿,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肺魁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鹅经,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門贷痪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蹦误,“玉大人肉津,你說(shuō)我怎么就攤上這事舱沧。” “怎么了狗唉?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵分俯,是天一觀的道長(zhǎng)哆料。 經(jīng)常有香客問(wèn)我,道長(zhǎng)东亦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任奋渔,我火速辦了婚禮,結(jié)果婚禮上嫉鲸,老公的妹妹穿的比我還像新娘歹啼。我一直安慰自己,他們只是感情好狸眼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著岁钓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪甜紫。 梳的紋絲不亂的頭發(fā)上骂远,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音拓型,去河邊找鬼额嘿。 笑死劣挫,一個(gè)胖子當(dāng)著我的面吹牛册养,可吹牛的內(nèi)容都是我干的压固。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼坎炼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼拦键!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起芬为,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎媚朦,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體福稳,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瑞侮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了半火。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梅掠,死狀恐怖店归,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情消痛,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布逞带,位于F島的核電站欺矫,受9級(jí)特大地震影響展氓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜遇汞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望络它。 院中可真熱鬧执庐,春花似錦导梆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)藏斩。三九已至,卻和暖如春狰域,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背兆览。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工抬探, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人小压。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像怠益,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蜻牢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容