記一次網(wǎng)絡(luò)連接bug解決

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給硬件。


IPhone資源釋放.jpg

在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)了


Android默認(rèn)資源釋放.jpg

懷著興奮地心情嘗試調(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è)整理吧

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,234評(píng)論 25 708
  • 用兩張圖告訴你,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 14,054評(píng)論 2 59
  • 1、TCP狀態(tài)linux查看tcp的狀態(tài)命令:1)、netstat -nat 查看TCP各個(gè)狀態(tài)的數(shù)量2)、lso...
    北辰青閱讀 9,728評(píng)論 0 11
  • 18.1 引言 TCP是一個(gè)面向連接的協(xié)議。無(wú)論哪一方向另一方發(fā)送數(shù)據(jù)之前,都必須先在雙方之間建立一條連接。本章將...
    張芳濤閱讀 3,529評(píng)論 0 13
  • 工作中事務(wù)繁雜瑣屑,難免疏漏。補(bǔ)救措施就是多方尋求協(xié)助,在最短時(shí)間單位內(nèi)把疏漏彌補(bǔ)。 總結(jié)~只有看見(jiàn)問(wèn)題才能真正解...
    寧?kù)o致遠(yuǎn)05閱讀 358評(píng)論 0 1

友情鏈接更多精彩內(nèi)容