本篇文章為大家展示了怎么進(jìn)行TCP異常關(guān)閉的問題分析,內(nèi)容簡明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
創(chuàng)新互聯(lián)主要從事網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)順慶,10年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):028-86922220
研究測試TCP斷開和異常的各種情況,以便于分析網(wǎng)絡(luò)應(yīng)用(比如tconnd)斷網(wǎng)的原因和場景,幫組分析和定位連接異常掉線的問題,并提供給TCP相關(guān)的開發(fā)測試人員作為參考。
各個(gè)游戲接入都存在一定的掉線問題,而且有的游戲項(xiàng)目的掉線比例還比較高,現(xiàn)在互娛自研游戲的網(wǎng)絡(luò)接入基本上都用的是tconnd和ProtocalHandler組件,因此參與其掉線原因分析和研究。
在參與A項(xiàng)目的掉線問題研究分析過程中,tconnd增加了玩家每個(gè)連接的流水日志和ProtocalHandler增加了每個(gè)連接的Qos上報(bào)日志,通過這些日志記錄了每一次連接的斷開原因和相關(guān)統(tǒng)計(jì)數(shù)據(jù),其中包括了連接異常斷開時(shí)TCP的底層錯(cuò)誤碼。
通過對(duì)tconnd的流水日志和ProtocalHandler的Qos日志進(jìn)行統(tǒng)計(jì)分析,發(fā)現(xiàn)連接異常斷開時(shí)TCP的錯(cuò)誤碼大部分是“104: Connection reset by peer
”(Linux下)或“10054: An existing connection was forcibly closed by the remote host
”(Windows下),單純從錯(cuò)誤碼本來來說,大家都明白是“網(wǎng)絡(luò)被對(duì)端重置了”,但究竟什么情況下會(huì)導(dǎo)致這種情況呢?因此就對(duì)TCP的各種關(guān)閉情況做了進(jìn)一步的測試研究。
服務(wù)器程序在接受客戶端的TCP連接后Sleep幾秒鐘,客戶端程序在TCP連接后立即發(fā)送很多消息給對(duì)端后做相應(yīng)動(dòng)作(退出或等待),服務(wù)器程序Sleep完后開始Recv消息。
注意:服務(wù)器程序測試了Linux和Windows版本,但客戶端只測試了Windows版本,如果是Linux客戶端則有些Case的結(jié)果會(huì)不一樣。
客戶端程序正常運(yùn)行的情況下,拔掉網(wǎng)線,殺掉客戶端程序
目的:模擬客戶端死機(jī)、系統(tǒng)突然重啟、網(wǎng)線松動(dòng)或網(wǎng)絡(luò)不通等情況。
結(jié)論:這種情況下服務(wù)器程序沒有檢測到任何異常,并最后等待“超時(shí)”才斷開TCP連接。
客戶端程序發(fā)送很多數(shù)據(jù)包后正常關(guān)閉Socket并exit進(jìn)程(或不退出進(jìn)程)
目的:模擬客戶端發(fā)送完消息后正常退出的情況。
結(jié)論:這種情況下服務(wù)器程序能夠成功接收完所有消息,并最后收到“對(duì)端關(guān)閉”(Recv返回零)消息。
客戶端程序發(fā)送很多數(shù)據(jù)包后不關(guān)閉Socket直接exit進(jìn)程
目的:模擬客戶端程序退出而忘記關(guān)閉Socket的情況(比如通過Windows窗口的關(guān)閉圖標(biāo)退出進(jìn)程,而沒有捕獲相應(yīng)關(guān)閉事件做正常退出處理等)。
結(jié)論:這種情況下服務(wù)器程序能夠收到部分TCP消息,然后收到“104: Connection reset by peer”(Linux下)或“10054: An existing connection was forcibly closed by the remote host”(Windows下)錯(cuò)誤。
客戶端程序發(fā)送很多數(shù)據(jù)包的過程中直接Kill進(jìn)程
目的:模擬客戶端程序崩潰或非正常方式結(jié)束進(jìn)程(比如Linux下"kill -9"或Windows的任務(wù)管理器殺死進(jìn)程)的情況。
結(jié)論:這種情況下服務(wù)器程序很快收到“104: Connection reset by peer
”(Linux下)或“10054: An existing connection was forcibly closed by the remote host
”(Windows下)錯(cuò)誤。
服務(wù)器程序在接受客戶端的TCP連接后Sleep幾秒鐘,客戶端程序在TCP連接后立即發(fā)送很多消息給對(duì)端后做相應(yīng)動(dòng)作(退出或等待),服務(wù)器程序Sleep完后開始Recv和Send消息。
注意:服務(wù)器程序測試了Linux和Windows版本,但客戶端只測試了Windows版本,如果是Linux客戶端則有些Case的結(jié)果可能會(huì)不一樣。
客戶端程序發(fā)送很多數(shù)據(jù)包后正常關(guān)閉Socket并exit進(jìn)程(或不退出進(jìn)程)
目的:模擬客戶端正常關(guān)閉Socket后,服務(wù)器端在檢查到TCP對(duì)端關(guān)閉前向客戶端發(fā)送消息的情況。
結(jié)論:這種情況下服務(wù)器程序接收和發(fā)送部分TCP消息后,在Send消息時(shí)產(chǎn)生“32: Broken pipe”(Linux下)或“10053: An established connection was aborted by the software in your host machine”(Windows下)錯(cuò)誤。
客戶端程序發(fā)送很多數(shù)據(jù)包后不關(guān)閉Socket直接exit或Kill進(jìn)程
目的:模擬客戶端程序退出而忘記關(guān)閉Socket、或客戶端程序崩潰或非正常方式結(jié)束進(jìn)程的情況。
結(jié)論:這種情況下服務(wù)器程序在Recv或Send消息時(shí)產(chǎn)生“104: Connection reset by peer
”(Linux下)或“10054: An existing connection was forcibly closed by the remote host
”(Windows下)錯(cuò)誤。
TCP發(fā)現(xiàn)網(wǎng)絡(luò)異常(特別是Linux下的104錯(cuò)誤或Windows下10054錯(cuò)誤)的情況很多,比如網(wǎng)絡(luò)本身的問題、中間路由器問題、網(wǎng)卡驅(qū)動(dòng)器問題等不可抗拒因素,但下面是應(yīng)用程序本身可能會(huì)導(dǎo)致的問題,也是我們需要進(jìn)一步研究和解決的情況,特別是程序崩潰導(dǎo)致問題:
當(dāng)TCP連接的進(jìn)程在忘記關(guān)閉Socket而退出、程序崩潰、或非正常方式結(jié)束進(jìn)程的情況下
(Windows客戶端),會(huì)導(dǎo)致TCP連接的對(duì)端進(jìn)程產(chǎn)生“104: Connection reset by peer
”(Linux下)或“10054: An existing connection was forcibly closed by the remote hos
t”(Windows下)錯(cuò)誤。
當(dāng)TCP連接的進(jìn)程機(jī)器發(fā)生死機(jī)、系統(tǒng)突然重啟、網(wǎng)線松動(dòng)或網(wǎng)絡(luò)不通等情況下
-(Windows客戶端),連接的對(duì)端進(jìn)程可能檢測不到任何異常,并最后等待“超時(shí)”才斷開TCP連接。
當(dāng)TCP連接的進(jìn)程正常關(guān)閉Socket時(shí),對(duì)端進(jìn)程在檢查到TCP關(guān)閉事件之前仍然向TCP發(fā)送消息
(Windows客戶端),則在Send消息時(shí)會(huì)產(chǎn)生“32: Broken pipe
”(Linux下)或“10053: An established connection was aborted by the software in your host machine
”(Windows下)錯(cuò)誤。
針對(duì)A項(xiàng)目的掉線問題,通過問卷調(diào)查和聯(lián)系個(gè)別玩家等方法,發(fā)現(xiàn)掉線的情況很大部分是客戶端程序直接退出了,因此推動(dòng)項(xiàng)目組實(shí)現(xiàn)了客戶端的Qos上報(bào)功能,最后通過客戶端的Qos上報(bào)的統(tǒng)計(jì)數(shù)據(jù)得出客戶端程序的崩潰比例比較高,占了總掉線的很大比率,當(dāng)然其它情況也存在,但比例相對(duì)比較小。
因此,A項(xiàng)目首先應(yīng)該解決客戶端程序的崩潰問題,如果該問題解決了,也就解決大部分掉線問題。
B項(xiàng)目游戲在跨服跳轉(zhuǎn)時(shí)的掉線比例比較高,經(jīng)過分析ProtocalHandler和tconnd的日志,發(fā)現(xiàn)掉線出現(xiàn)的情況是:tconnd發(fā)送了跨服跳轉(zhuǎn)消息后立即關(guān)閉了Socket,客戶端進(jìn)程在接收到跨服跳轉(zhuǎn)消息之前發(fā)送消息后收到Windows 10054錯(cuò)誤,然后做斷線重連失敗。
B項(xiàng)目實(shí)現(xiàn)跨服跳轉(zhuǎn)的流程是GameSvr給客戶端程序下發(fā)的跨服跳轉(zhuǎn)命令的同時(shí)攜帶了Stop請(qǐng)求,也就是說tconnd在向客戶端轉(zhuǎn)發(fā)跨服跳轉(zhuǎn)消息后立即就會(huì)關(guān)閉當(dāng)前的Socket連接,而且B項(xiàng)目的客戶端程序會(huì)定期不斷地向服務(wù)器上報(bào)消息。這又怎么會(huì)導(dǎo)致客戶端程序收到10054錯(cuò)誤而呢?鑒于此,對(duì)TCP的連接做進(jìn)一步的場景測試分析。
客戶端和服務(wù)器端程序建立TCP連接,服務(wù)器程序在TCP緩沖區(qū)中有消息或沒有消息的情況下關(guān)閉Socket,客戶端在對(duì)端Socket已經(jīng)關(guān)閉的情況下繼續(xù)Send和Recv消息。
注意:服務(wù)器端只測試了Linux版本,但客戶端測試了Windows和Linux兩個(gè)版本。
服務(wù)器端已經(jīng)close了Socket,客戶端再發(fā)送數(shù)據(jù)
目的:測試在TCP對(duì)端進(jìn)程已經(jīng)關(guān)閉Socket時(shí),本端進(jìn)程還未檢測到連接關(guān)閉的情況下繼續(xù)向?qū)Χ税l(fā)送消息。
結(jié)論:第一包可以發(fā)送成功,但第二包發(fā)送失敗,錯(cuò)誤碼為“10053: An established connection was aborted by the software in your host machine
”(Windows下)或“32: Broken pipe,同時(shí)收到SIGPIPE信號(hào)
”(Linux下)錯(cuò)誤。
服務(wù)器端發(fā)送數(shù)據(jù)到TCP后close了Socket,客戶端再發(fā)送一包數(shù)據(jù),然后接收消息
目的:測試在TCP對(duì)端進(jìn)程發(fā)送數(shù)據(jù)后關(guān)閉Socket,本端進(jìn)程還未檢測到連接關(guān)閉的情況下發(fā)送一包消息,接著接收消息。
結(jié)論:客戶端能夠成功發(fā)送第一包數(shù)據(jù)(這會(huì)導(dǎo)致服務(wù)器端發(fā)送一個(gè)RST包 <已抓包驗(yàn)證>),客戶端再去Recv時(shí),對(duì)于Windows和Linux程序有如下不同的表現(xiàn):
Windows客戶端程序:Recv失敗,錯(cuò)誤碼為“10053: An established connection was aborted by the software in your host machine
”。
Linux客戶端程序:能正常接收完所有消息包,最后收到正常的對(duì)端關(guān)閉消息(這一點(diǎn)與Window下不一樣,RST包沒有被提前接收到)。
服務(wù)器端在TCP的接收緩沖區(qū)中還有未接收數(shù)據(jù)的情況下close了Socket,客戶端再收包
目的:測試在TCP的接收緩沖區(qū)中還有未接收數(shù)據(jù)的情況下關(guān)閉Socket時(shí),對(duì)端進(jìn)程是否正常。
結(jié)論:這種情況服務(wù)器端就會(huì)向?qū)Χ税l(fā)送RST包,而不是正常的FIN包(已經(jīng)抓包證明),這就會(huì)導(dǎo)致客戶端提前(RST包比正常數(shù)據(jù)包先被收到)收到“10054: An existing connection was forcibly closed by the remote host
”(Windows下)或“104: Connection reset by peer
”(Linux下)錯(cuò)誤。
TCP應(yīng)用程序某些看是正常的行為下也可能會(huì)導(dǎo)致對(duì)端接收到異常,比如當(dāng)TCP接收緩沖區(qū)中還有未收數(shù)據(jù)的情況下關(guān)閉Socket,則會(huì)導(dǎo)致對(duì)端接收到異常關(guān)閉而不是正常關(guān)閉;反過來說,當(dāng)TCP檢測到異常關(guān)閉時(shí)并不一定表示業(yè)務(wù)上出問題了,因?yàn)楹芸赡芫褪菢I(yè)務(wù)正常結(jié)束了。下面是本次測試的主要結(jié)論:
當(dāng)TCP連接的對(duì)端進(jìn)程已經(jīng)關(guān)閉了Socket的情況下,本端進(jìn)程再發(fā)送數(shù)據(jù)時(shí),第一包可以發(fā)送成功(但會(huì)導(dǎo)致對(duì)端發(fā)送一個(gè)RST包過來):之后如果再繼續(xù)發(fā)送數(shù)據(jù)會(huì)失敗,錯(cuò)誤碼為“10053: An established connection was aborted by the software in your host machine
”(Windows下)或“32: Broken pipe,同時(shí)收到SIGPIPE信號(hào)”(Linux下)錯(cuò)誤;之后如果接收數(shù)據(jù),則Windows下會(huì)報(bào)10053的錯(cuò)誤,而Linux下則收到正常關(guān)閉消息。
TCP連接的本端接收緩沖區(qū)中還有未接收數(shù)據(jù)的情況下close了Socket,則本端TCP會(huì)向?qū)Χ税l(fā)送RST包,而不是正常的FIN包,這就會(huì)導(dǎo)致對(duì)端進(jìn)程提前(RST包比正常數(shù)據(jù)包先被收到)收到“10054: An existing connection was forcibly closed by the remote host
”(Windows下)或“104: Connection reset by peer
”(Linux下)錯(cuò)誤。
B項(xiàng)目跨服跳轉(zhuǎn)的掉線問題有相當(dāng)一部分的種情況是tconnd向客戶端轉(zhuǎn)發(fā)跨服跳轉(zhuǎn)消息后立即關(guān)閉Socket連接,而此時(shí)剛好客戶端向tconnd發(fā)送了數(shù)據(jù)包:
第一種情況:tconnd在關(guān)閉Socket的時(shí)刻其TCP的接收緩沖區(qū)中有未收的消息,這就使得tconnd進(jìn)程的TCP向客戶端發(fā)送的是RST包而不是正常結(jié)束的FIN包,所以客戶端程序就會(huì)提前收到RST包(RST包會(huì)比正常數(shù)據(jù)提前收到),而不會(huì)先收完跨服跳轉(zhuǎn)消息后再接收到正常結(jié)束消息,這就導(dǎo)致客戶端收到網(wǎng)絡(luò)異常斷線而做重連,但之前的連接是tconnd主動(dòng)關(guān)閉的,所以不可能重連成功,從而導(dǎo)致掉線。
第二種情況:tconnd已經(jīng)關(guān)閉了Socket后,客戶端在接收到跳轉(zhuǎn)消息和檢測到TCP關(guān)閉之前向tconnd發(fā)送了消息,這就會(huì)導(dǎo)致客戶端程序收到異常斷線而做重連并失敗。
最后,與B項(xiàng)目項(xiàng)目組一起討論,改進(jìn)了大部分跨服跳轉(zhuǎn)的業(yè)務(wù)流程后,掉線比例j減少了很多,當(dāng)然還是存在一定比例的掉線,但這應(yīng)該就是其它一些原因了(網(wǎng)絡(luò)異常問題原因很多,國內(nèi)當(dāng)前的網(wǎng)絡(luò)環(huán)境下,掉線問題是不可能完全避免的)。
通常情況下,向TCP的Socket發(fā)送完數(shù)據(jù)后關(guān)閉Socket,大家認(rèn)為這樣很正常的方式肯定沒有問題,對(duì)端應(yīng)該正確收完數(shù)據(jù)后收到TCP的關(guān)閉消息,但實(shí)際上在某些情況下并非如此:當(dāng)TCP本端的接收緩沖區(qū)中有未收的數(shù)據(jù)時(shí)關(guān)閉Socket,這會(huì)導(dǎo)致對(duì)端收到RST的異常關(guān)閉消息;當(dāng)對(duì)端在本端已經(jīng)關(guān)閉Socket的情況下再次發(fā)送消息時(shí),也會(huì)導(dǎo)致對(duì)端收到異常關(guān)閉消息;還有為了避免TIME_WAIT而設(shè)置了SO_LINGER選項(xiàng)的話,也會(huì)導(dǎo)致連接提前夭折使對(duì)端收到RST異常關(guān)閉消息。
有些時(shí)候業(yè)務(wù)流程對(duì)是否引起掉線也很重要(特別是連接關(guān)閉流程),比如前面的B項(xiàng)目的跨服跳轉(zhuǎn)掉線問題很大部分就是因?yàn)镚ameSvr請(qǐng)求關(guān)閉連接導(dǎo)致的。建議各個(gè)游戲項(xiàng)目的關(guān)閉流程(包括跨服跳轉(zhuǎn)的原連接的關(guān)閉)最好都由客戶端發(fā)起關(guān)閉,這樣就一定程度上避免上述問題的發(fā)生(因?yàn)榭头税l(fā)起關(guān)閉的時(shí)候,一般業(yè)務(wù)流程都走完了,服務(wù)器端也不會(huì)再向客戶端發(fā)送消息了)。
程序收到網(wǎng)絡(luò)異常的情況很多(最多的就是Linux下的104錯(cuò)誤和Windos下的10054/10053錯(cuò)誤):有網(wǎng)絡(luò)本身的問題、也有應(yīng)用使用不當(dāng)?shù)膯栴};有運(yùn)營商之間的跨網(wǎng)絡(luò)問題、網(wǎng)絡(luò)中間路由器問題、玩家機(jī)器硬件(比如網(wǎng)卡及其驅(qū)動(dòng))問題和操作系統(tǒng)、殺毒軟件、防火墻等軟件問題,還有玩家的上網(wǎng)設(shè)備和路由器等中間設(shè)備問題等,但客戶端程序崩潰問題有可能會(huì)占掉線的很高比例,這也是值得我們注意和改進(jìn)的地方。還有種情況值得我們注意,有些TP-LINK的路由器,當(dāng)UDP包大小超過其MTU值時(shí)會(huì)導(dǎo)致用戶機(jī)器的網(wǎng)絡(luò)斷開,從而引起掉線(這個(gè)問題在某些項(xiàng)目的個(gè)別玩家中已經(jīng)出現(xiàn)過)。
網(wǎng)絡(luò)異常關(guān)閉引起掉線是當(dāng)前游戲中普遍存在的問題,區(qū)別只在于掉線的比例多少,特別是國內(nèi)各運(yùn)營商之間跨網(wǎng)絡(luò)訪問更是不太順暢,要將其完全消除是不可能的,但我們的目標(biāo)是將其控制在較小的可接受范圍內(nèi)。
上述內(nèi)容就是怎么進(jìn)行TCP異常關(guān)閉的問題分析,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
分享文章:怎么進(jìn)行TCP異常關(guān)閉的問題分析
本文網(wǎng)址:http://jinyejixie.com/article40/ppisho.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、靜態(tài)網(wǎng)站、微信小程序、網(wǎng)站收錄、軟件開發(fā)、標(biāo)簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)