久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

怎么進行TCP異常關閉的問題分析

217次閱讀
沒有評論

共計 6151 個字符,預計需要花費 16 分鐘才能閱讀完成。

本篇文章為大家展示了怎么進行 TCP 異常關閉的問題分析,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

研究測試 TCP 斷開和異常的各種情況,以便于分析網絡應用(比如 tconnd)斷網的原因和場景,幫組分析和定位連接異常掉線的問題,并提供給 TCP 相關的開發測試人員作為參考。

各個游戲接入都存在一定的掉線問題,而且有的游戲項目的掉線比例還比較高,現在互娛自研游戲的網絡接入基本上都用的是 tconnd 和 ProtocalHandler 組件,因此參與其掉線原因分析和研究。

在參與 A 項目的掉線問題研究分析過程中,tconnd 增加了玩家每個連接的流水日志和 ProtocalHandler 增加了每個連接的 Qos 上報日志,通過這些日志記錄了每一次連接的斷開原因和相關統計數據,其中包括了連接異常斷開時 TCP 的底層錯誤碼。

通過對 tconnd 的流水日志和 ProtocalHandler 的 Qos 日志進行統計分析,發現連接異常斷開時 TCP 的錯誤碼大部分是“104: Connection reset by peer”(Linux 下)或“10054: An existing connection was forcibly closed by the remote host”(Windows 下),單純從錯誤碼本來來說,大家都明白是“網絡被對端重置了”,但究竟什么情況下會導致這種情況呢?因此就對 TCP 的各種關閉情況做了進一步的測試研究。

一. TCP 異常關閉的研究測試 1. 服務器端只 Recv 消息而不 Send 消息 1.1 測試方法

服務器程序在接受客戶端的 TCP 連接后 Sleep 幾秒鐘,客戶端程序在 TCP 連接后立即發送很多消息給對端后做相應動作(退出或等待),服務器程序 Sleep 完后開始 Recv 消息。

注意:服務器程序測試了 Linux 和 Windows 版本,但客戶端只測試了 Windows 版本,如果是 Linux 客戶端則有些 Case 的結果會不一樣。

1.2 測試 Case

客戶端程序正常運行的情況下,拔掉網線,殺掉客戶端程序
目的:模擬客戶端死機、系統突然重啟、網線松動或網絡不通等情況。
結論:這種情況下服務器程序沒有檢測到任何異常,并最后等待“超時”才斷開 TCP 連接。

客戶端程序發送很多數據包后正常關閉 Socket 并 exit 進程 (或不退出進程)
目的:模擬客戶端發送完消息后正常退出的情況。
結論:這種情況下服務器程序能夠成功接收完所有消息,并最后收到“對端關閉”(Recv 返回零)消息。

客戶端程序發送很多數據包后不關閉 Socket 直接 exit 進程
目的:模擬客戶端程序退出而忘記關閉 Socket 的情況(比如通過 Windows 窗口的關閉圖標退出進程,而沒有捕獲相應關閉事件做正常退出處理等)。
結論:這種情況下服務器程序能夠收到部分 TCP 消息,然后收到“104: Connection reset by peer”(Linux 下)或“10054: An existing connection was forcibly closed by the remote host”(Windows 下)錯誤。

客戶端程序發送很多數據包的過程中直接 Kill 進程
目的:模擬客戶端程序崩潰或非正常方式結束進程(比如 Linux 下 kill -9 或 Windows 的任務管理器殺死進程)的情況。
結論:這種情況下服務器程序很快收到“104: Connection reset by peer”(Linux 下)或“10054: An existing connection was forcibly closed by the remote host”(Windows 下)錯誤。

2. 服務器端 Recv 消息并 Send 應答消息 2.1 測試方法

服務器程序在接受客戶端的 TCP 連接后 Sleep 幾秒鐘,客戶端程序在 TCP 連接后立即發送很多消息給對端后做相應動作(退出或等待),服務器程序 Sleep 完后開始 Recv 和 Send 消息。

注意:服務器程序測試了 Linux 和 Windows 版本,但客戶端只測試了 Windows 版本,如果是 Linux 客戶端則有些 Case 的結果可能會不一樣。

2.2 測試結果

客戶端程序發送很多數據包后正常關閉 Socket 并 exit 進程(或不退出進程)
目的:模擬客戶端正常關閉 Socket 后,服務器端在檢查到 TCP 對端關閉前向客戶端發送消息的情況。
結論:這種情況下服務器程序接收和發送部分 TCP 消息后,在 Send 消息時產生“32: Broken pipe”(Linux 下)或“10053: An established connection was aborted by the software in your host machine”(Windows 下)錯誤。

客戶端程序發送很多數據包后不關閉 Socket 直接 exit 或 Kill 進程
目的:模擬客戶端程序退出而忘記關閉 Socket、或客戶端程序崩潰或非正常方式結束進程的情況。
結論:這種情況下服務器程序在 Recv 或 Send 消息時產生“104: Connection reset by peer”(Linux 下)或“10054: An existing connection was forcibly closed by the remote host”(Windows 下)錯誤。

3. 效果和總結 3.1 總結

TCP 發現網絡異常(特別是 Linux 下的 104 錯誤或 Windows 下 10054 錯誤)的情況很多,比如網絡本身的問題、中間路由器問題、網卡驅動器問題等不可抗拒因素,但下面是應用程序本身可能會導致的問題,也是我們需要進一步研究和解決的情況,特別是程序崩潰導致問題:

當 TCP 連接的進程在忘記關閉 Socket 而退出、程序崩潰、或非正常方式結束進程的情況下
(Windows 客戶端),會導致 TCP 連接的對端進程產生“104: Connection reset by peer”(Linux 下)或“10054: An existing connection was forcibly closed by the remote host”(Windows 下)錯誤。

當 TCP 連接的進程機器發生死機、系統突然重啟、網線松動或網絡不通等情況下
-(Windows 客戶端),連接的對端進程可能檢測不到任何異常,并最后等待“超時”才斷開 TCP 連接。

當 TCP 連接的進程正常關閉 Socket 時,對端進程在檢查到 TCP 關閉事件之前仍然向 TCP 發送消息
(Windows 客戶端),則在 Send 消息時會產生“32: Broken pipe”(Linux 下)或“10053: An established connection was aborted by the software in your host machine”(Windows 下)錯誤。

3.2 效果

針對 A 項目的掉線問題,通過問卷調查和聯系個別玩家等方法,發現掉線的情況很大部分是客戶端程序直接退出了,因此推動項目組實現了客戶端的 Qos 上報功能,最后通過客戶端的 Qos 上報的統計數據得出客戶端程序的崩潰比例比較高,占了總掉線的很大比率,當然其它情況也存在,但比例相對比較小。

因此,A 項目首先應該解決客戶端程序的崩潰問題,如果該問題解決了,也就解決大部分掉線問題。

二. TCP 異常關閉的進一步研究測試 1. 背景

B 項目游戲在跨服跳轉時的掉線比例比較高,經過分析 ProtocalHandler 和 tconnd 的日志,發現掉線出現的情況是:tconnd 發送了跨服跳轉消息后立即關閉了 Socket,客戶端進程在接收到跨服跳轉消息之前發送消息后收到 Windows 10054 錯誤,然后做斷線重連失敗。

B 項目實現跨服跳轉的流程是 GameSvr 給客戶端程序下發的跨服跳轉命令的同時攜帶了 Stop 請求,也就是說 tconnd 在向客戶端轉發跨服跳轉消息后立即就會關閉當前的 Socket 連接,而且 B 項目的客戶端程序會定期不斷地向服務器上報消息。這又怎么會導致客戶端程序收到 10054 錯誤而呢?鑒于此,對 TCP 的連接做進一步的場景測試分析。

2. TCP 異常進一步測試研究 2.1 測試方法

客戶端和服務器端程序建立 TCP 連接,服務器程序在 TCP 緩沖區中有消息或沒有消息的情況下關閉 Socket,客戶端在對端 Socket 已經關閉的情況下繼續 Send 和 Recv 消息。

注意:服務器端只測試了 Linux 版本,但客戶端測試了 Windows 和 Linux 兩個版本。

2.2 測試結果

服務器端已經 close 了 Socket,客戶端再發送數據
目的:測試在 TCP 對端進程已經關閉 Socket 時,本端進程還未檢測到連接關閉的情況下繼續向對端發送消息。
結論:第一包可以發送成功,但第二包發送失敗,錯誤碼為“10053: An established connection was aborted by the software in your host machine”(Windows 下)或“32: Broken pipe,同時收到 SIGPIPE 信號”(Linux 下)錯誤。

服務器端發送數據到 TCP 后 close 了 Socket,客戶端再發送一包數據,然后接收消息
目的:測試在 TCP 對端進程發送數據后關閉 Socket,本端進程還未檢測到連接關閉的情況下發送一包消息,接著接收消息。
結論:客戶端能夠成功發送第一包數據(這會導致服務器端發送一個 RST 包 已抓包驗證),客戶端再去 Recv 時,對于 Windows 和 Linux 程序有如下不同的表現:
Windows 客戶端程序:Recv 失敗,錯誤碼為“10053: An established connection was aborted by the software in your host machine”。
Linux 客戶端程序:能正常接收完所有消息包,最后收到正常的對端關閉消息(這一點與 Window 下不一樣,RST 包沒有被提前接收到)。

服務器端在 TCP 的接收緩沖區中還有未接收數據的情況下 close 了 Socket,客戶端再收包
目的:測試在 TCP 的接收緩沖區中還有未接收數據的情況下關閉 Socket 時,對端進程是否正常。
結論:這種情況服務器端就會向對端發送 RST 包,而不是正常的 FIN 包(已經抓包證明),這就會導致客戶端提前(RST 包比正常數據包先被收到)收到“10054: An existing connection was forcibly closed by the remote host”(Windows 下)或“104: Connection reset by peer”(Linux 下)錯誤。

3 效果和總結 3.1 總結

TCP 應用程序某些看是正常的行為下也可能會導致對端接收到異常,比如當 TCP 接收緩沖區中還有未收數據的情況下關閉 Socket,則會導致對端接收到異常關閉而不是正常關閉;反過來說,當 TCP 檢測到異常關閉時并不一定表示業務上出問題了,因為很可能就是業務正常結束了。下面是本次測試的主要結論:

當 TCP 連接的對端進程已經關閉了 Socket 的情況下,本端進程再發送數據時,第一包可以發送成功(但會導致對端發送一個 RST 包過來):之后如果再繼續發送數據會失敗,錯誤碼為“10053: An established connection was aborted by the software in your host machine”(Windows 下)或“32: Broken pipe,同時收到 SIGPIPE 信號”(Linux 下)錯誤;之后如果接收數據,則 Windows 下會報 10053 的錯誤,而 Linux 下則收到正常關閉消息。

TCP 連接的本端接收緩沖區中還有未接收數據的情況下 close 了 Socket,則本端 TCP 會向對端發送 RST 包,而不是正常的 FIN 包,這就會導致對端進程提前(RST 包比正常數據包先被收到)收到“10054: An existing connection was forcibly closed by the remote host”(Windows 下)或“104: Connection reset by peer”(Linux 下)錯誤。

3.2 效果

B 項目跨服跳轉的掉線問題有相當一部分的種情況是 tconnd 向客戶端轉發跨服跳轉消息后立即關閉 Socket 連接,而此時剛好客戶端向 tconnd 發送了數據包:

第一種情況:tconnd 在關閉 Socket 的時刻其 TCP 的接收緩沖區中有未收的消息,這就使得 tconnd 進程的 TCP 向客戶端發送的是 RST 包而不是正常結束的 FIN 包,所以客戶端程序就會提前收到 RST 包(RST 包會比正常數據提前收到),而不會先收完跨服跳轉消息后再接收到正常結束消息,這就導致客戶端收到網絡異常斷線而做重連,但之前的連接是 tconnd 主動關閉的,所以不可能重連成功,從而導致掉線。

第二種情況:tconnd 已經關閉了 Socket 后,客戶端在接收到跳轉消息和檢測到 TCP 關閉之前向 tconnd 發送了消息,這就會導致客戶端程序收到異常斷線而做重連并失敗。

最后,與 B 項目項目組一起討論,改進了大部分跨服跳轉的業務流程后,掉線比例 j 減少了很多,當然還是存在一定比例的掉線,但這應該就是其它一些原因了(網絡異常問題原因很多,國內當前的網絡環境下,掉線問題是不可能完全避免的)。

通常情況下,向 TCP 的 Socket 發送完數據后關閉 Socket,大家認為這樣很正常的方式肯定沒有問題,對端應該正確收完數據后收到 TCP 的關閉消息,但實際上在某些情況下并非如此:當 TCP 本端的接收緩沖區中有未收的數據時關閉 Socket,這會導致對端收到 RST 的異常關閉消息;當對端在本端已經關閉 Socket 的情況下再次發送消息時,也會導致對端收到異常關閉消息;還有為了避免 TIME_WAIT 而設置了 SO_LINGER 選項的話,也會導致連接提前夭折使對端收到 RST 異常關閉消息。

有些時候業務流程對是否引起掉線也很重要(特別是連接關閉流程),比如前面的 B 項目的跨服跳轉掉線問題很大部分就是因為 GameSvr 請求關閉連接導致的。建議各個游戲項目的關閉流程(包括跨服跳轉的原連接的關閉)最好都由客戶端發起關閉,這樣就一定程度上避免上述問題的發生(因為客服端發起關閉的時候,一般業務流程都走完了,服務器端也不會再向客戶端發送消息了)。

程序收到網絡異常的情況很多(最多的就是 Linux 下的 104 錯誤和 Windos 下的 10054/10053 錯誤):有網絡本身的問題、也有應用使用不當的問題;有運營商之間的跨網絡問題、網絡中間路由器問題、玩家機器硬件(比如網卡及其驅動)問題和操作系統、殺毒軟件、防火墻等軟件問題,還有玩家的上網設備和路由器等中間設備問題等,但客戶端程序崩潰問題有可能會占掉線的很高比例,這也是值得我們注意和改進的地方。還有種情況值得我們注意,有些 TP-LINK 的路由器,當 UDP 包大小超過其 MTU 值時會導致用戶機器的網絡斷開,從而引起掉線(這個問題在某些項目的個別玩家中已經出現過)。

網絡異常關閉引起掉線是當前游戲中普遍存在的問題,區別只在于掉線的比例多少,特別是國內各運營商之間跨網絡訪問更是不太順暢,要將其完全消除是不可能的,但我們的目標是將其控制在較小的可接受范圍內。

上述內容就是怎么進行 TCP 異常關閉的問題分析,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注丸趣 TV 行業資訊頻道。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-16發表,共計6151字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 武汉市| 甘德县| 平安县| 昆山市| 敖汉旗| 承德县| 青田县| 罗江县| 汶上县| 嘉兴市| 宁乡县| 垦利县| 黄山市| 广南县| 呼图壁县| 彭阳县| 曲水县| 齐河县| 临夏县| 如皋市| 潜江市| 喀喇沁旗| 辰溪县| 靖远县| 武冈市| 清新县| 威远县| 凌海市| 大丰市| 萨迦县| 广安市| 壤塘县| 威远县| 资兴市| 虞城县| 黎川县| 庆安县| 浦东新区| 灵台县| 唐河县| 乌苏市|