bug背景
項(xiàng)目涉及到與硬件的交互,和硬件連接使用java中基于TCP/IP的兩個(gè)長(zhǎng)連接Socket連接同一端口,硬件僅支持兩個(gè)連接的建立,一旦建立,除非重置硬件Wifi模塊,否則不再接受新的連接。開(kāi)發(fā)過(guò)程中指導(dǎo)IOS開(kāi)發(fā)構(gòu)建了同一套PTP/IP連接模塊,結(jié)果IOS在進(jìn)程被殺死后,硬件會(huì)重置Wifi等待重新連接,而Android端APP進(jìn)程被殺死后,硬件沒(méi)有重置Wifi,所以不能直接重新連接需要手動(dòng)重啟硬件。
As far as we know, 所有UNIX-LIKE的系統(tǒng),在進(jìn)程被殺死時(shí)都會(huì)釋放資源,socket更是會(huì)先發(fā)送揮手包(FIN)及完成四次揮手,那么區(qū)別在哪里呢。
肯定不在前期指令執(zhí)行上,所有指令I(lǐng)OS和Android都是一樣的,那么只可能在資源釋放的環(huán)節(jié)了。
尋找IOS端和Android端進(jìn)程被殺死后Socket資源釋放的區(qū)別
環(huán)境
Macbook Pro + wireshark + python
IPhone
Android + root + busybox(tcpdump)
實(shí)操
由于區(qū)別主要在于TCP斷開(kāi)連接的方式,抓包最好使用wireshark,通過(guò)IPhone連接電腦,執(zhí)行
rvictl -s 193c851574d6e7225bd9447ae03f55c5b5195802
抓取IOS所有通過(guò)當(dāng)前wifi網(wǎng)卡的數(shù)據(jù)包,發(fā)現(xiàn)進(jìn)程被殺死時(shí),一個(gè)Socket發(fā)送了FIN數(shù)據(jù)包后完成了四次揮手(client FIN->server ACK-> server FIN -> client ACK),而另一個(gè)Socket使用發(fā)送了RST給硬件。

在Android中看看Socket是怎么斷開(kāi)連接的,root后裝上busybox,執(zhí)行
adb shell su -c tcpdump
可以直接在終端看數(shù)據(jù)包,如果想要導(dǎo)入wireshark中可保存數(shù)據(jù)到文件再使用wireshark打開(kāi)或直接使用管道,在此不再贅述。發(fā)現(xiàn)Android中進(jìn)程被殺死后,兩個(gè)Socket都以四次揮手方式斷開(kāi)了

懷著興奮地心情嘗試調(diào)為一個(gè)用RST方式斷開(kāi),一個(gè)以四次揮手?jǐn)嚅_(kāi),在Java中如果想要Socket以RST方式斷開(kāi)連接,需要Socket參數(shù)linger為true,于是乎在Android客戶端對(duì)應(yīng)的Socket建立連接后,設(shè)置linger為true
socketMain.setSoLinger(true, 0)
完成后嘗試,發(fā)現(xiàn)沒(méi)有什么卵用。苦悶。。。
在苦思無(wú)果后,在Mac上嘗試用python和硬件建立連接,再殺死python進(jìn)程,看看硬件什么反應(yīng),花了幾分鐘寫(xiě)好python,監(jiān)聽(tīng)數(shù)據(jù)包,執(zhí)行,殺死,發(fā)現(xiàn)硬件重置了Wifi模塊,興奮。。??纯磾?shù)據(jù)包,發(fā)現(xiàn)兩個(gè)Socket都以RST方式斷開(kāi)了連接。。。
再次在Android中調(diào)整,給兩個(gè)Socket都設(shè)置linger為true,成了。
總結(jié)
此次bug解決在此敘述來(lái)很簡(jiǎn)單,但是總共耗時(shí)3天,期間嘗試了無(wú)數(shù)彎路,總結(jié)一下呢,bug原因仍然不知道,Android端硬件的官方應(yīng)用被殺死時(shí),兩個(gè)Socket斷開(kāi)也都是四次揮手的方式,但是反編譯其代碼發(fā)現(xiàn)其是使用的so庫(kù)實(shí)現(xiàn)的,暫時(shí)只能猜測(cè)和語(yǔ)言抽象等級(jí)或執(zhí)行環(huán)境有關(guān)。。C語(yǔ)言下使用FIN+FIN可行,OC下使用FIN+RST可行,python下和kotlin下使用RST+RST可行,感覺(jué)就像解釋執(zhí)行的代碼,需要RST。。
雖然bug很奇葩,但是解決過(guò)程也重溫了很多底層tcp/ip的知識(shí),工具使用也更熟練了...有時(shí)間再做個(gè)整理吧