WSAECONNABORTED 10053
Software caused connection abort.
An established connection was aborted by the software in your host computer, possibly due to a data transmission time-out or protocol error.
|
神馬?軟件原因造成的連接中斷,這是什么意思,不跟沒說一樣的么?
google一下唄
Berkeley description:
A connection abort was caused internal to your host machine. The software caused
a connection abort because there is no space on the socket’s queue and the socket
cannot receive further connections.
WinSock description:
Partly the same as Berkeley. The error can occur when the local network system aborts
a connection. This would occur if WinSock aborts an established connection after data
retransmission fails (receiver never acknowledges data sent on a datastream socket).
TCP/IP scenario:
A connection will timeout if the local system doesn’t receive an (ACK)nowledgement for
data sent. It would also timeout if a (FIN)ish TCP packet is not ACK’d
(and even if the FIN is ACK’d, it will eventually timeout if a FIN is not returned).
伯克利說這種連接中斷是因?yàn)樗拗鳈C(jī)器的內(nèi)部原因,因?yàn)檐浖?dǎo)致的連接中斷,可能是因?yàn)閟ocket的隊列滿并且這個socket不能接收更多的連接了。
這還不如不說,越說越糊涂了。
winsocket的描述,似乎還靠譜一些,這種錯誤一般發(fā)生在一個建立的連接被重發(fā)失敗的情況下產(chǎn)生,接收方?jīng)]有響應(yīng)數(shù)據(jù)發(fā)回來。但還是比較模糊。
再看看tcp ip標(biāo)準(zhǔn)文檔的說法,如果本地系統(tǒng)沒有收到發(fā)送數(shù)據(jù)的響應(yīng)(ack)那么這連接就會超時。如果tcp的fin包沒有被ack(或者fin包被ack了但fin沒有返回)那么也會超時。但是,但是,超時跟這個10053有神馬關(guān)系?
再看后續(xù)的解釋:
從參考1中找到如下的描述:
The Scenario:
An HTTP POST is to be sent to an HTTP server.
The server begins reading the POST and notices that the HTTP request header is invalid.
It immediately sends an HTTP response (with an error status, perhaps status=400) and closes the connection without trying to continue reading the remainder of the HTTP request that is forthcoming.
Meanwhile, the client is still happily writing the remainder of the HTTP request to the socket. (Remember a TCP/IP socket connection needs to be closed from both sides. In this case, the server has closed its side, but the client is still pumping data into the half-open connection.)
The client finishes writing the HTTP POST to the socket — meaning that data has been buffered to Winsock. The client application then tries to read the HTTP response, but it cannot because the outgoing retransmission (of the buffered data by WinSock) failed and the socket connection was shutdown on the client side (by Winsock). Even though the HTTP server sent the response, it is lost and cannot be retrieved. The error your application will receive when
trying to read the HTTP response on the socket is WSAECONNABORTED. The word "software" in any of the above error messages refers to "WinSock".
Go back and re-read the original error explanations. Hopefully, after that explanation, you’ll say "Aha! I understand what they’re talking about!".
啊哈,又有http了,大概意思就是http server收到請求了,但發(fā)現(xiàn)有問題,那么回一個http錯誤碼,然后就關(guān)閉了socket,但與此同時,client端還在很開心地向socket寫數(shù)據(jù),注意哦,tcp是全雙工的。client寫完畢后,實(shí)際上數(shù)據(jù)只是放到了發(fā)送方的緩沖區(qū)中,不一定已經(jīng)發(fā)出去了,如果寫得不好的程序,這個時候就開始從socket讀數(shù)據(jù)了,這時候就會產(chǎn)生一個WSACONNECTABORTED錯誤,windows上對應(yīng)的就是10053錯誤。
但這個解釋實(shí)際上是不能讓人滿意的,只是舉出了一種場景,但為什么會產(chǎn)生還沒有解釋。后面又搜到了個參考2,首先解釋10053錯誤是收到fin后client會放棄發(fā)送緩沖區(qū)中的數(shù)據(jù),同時上報錯誤。雖然說法還有點(diǎn)一頭霧水。
不過這兩個參考給我們一個思路,重現(xiàn)這個問題。
于是簡單寫個測試用的c-s程序,大概流程如下

圖1 CS程序簡化流程圖
這個簡單程序演示如何出現(xiàn)10053錯誤(以及10054錯誤)。
如果server在收到client發(fā)送的數(shù)據(jù)后立即關(guān)閉socket,那么client再讀時,會收到10053錯誤;如果server收到發(fā)送數(shù)據(jù)后,立即crash,那么隨后client再讀取時會收到10054錯誤。
ok,能夠重現(xiàn)場景了,那么我們來分析一下更細(xì)節(jié)的方面,網(wǎng)絡(luò)問題自然是抓包,本問題處理抓包還要看一下tcp的狀態(tài)以便輔助分析,我們在client端每次操作之前都打印當(dāng)前的tcp狀態(tài)。
下面是client端發(fā)送記錄和對應(yīng)的netstat情況
圖2 10053錯誤client端tcp狀態(tài)流轉(zhuǎn)
client在發(fā)送之前tcp狀態(tài)是established,在發(fā)送之后,server會立即關(guān)閉,tcp狀態(tài)也變?yōu)閏lose_wait,但這只是單方向的關(guān)閉,client可以繼續(xù)發(fā)數(shù)據(jù),但client發(fā)送后,server立即退出了,導(dǎo)致后續(xù)recv會失敗并且返回10053。對應(yīng)抓包情況如下:

圖3 10053錯誤client端tcp抓包
整個通信過程如下:
1-3.三次握手建立連接
4.客戶端(10.10.86.93)向服務(wù)器端(10.10.86.98)發(fā)送數(shù)據(jù),1字節(jié)
5.server 中止 發(fā)送fin(同時ack之前那個push)
6.client ack 那個fin
7.client再發(fā)送兩個字節(jié)
8.server此時已經(jīng)關(guān)閉socket,屬于非正常情況,回復(fù)復(fù)位命令
整個過程可以重現(xiàn)10053情況,tcp發(fā)送分組數(shù)據(jù)的情況也一目了然,事情到此就可以了么?顯然不是,你也看到了后面還有很多文字,不知此時你心中的問題是否跟我一樣,先說我自己的吧,通過抓包發(fā)現(xiàn)這里的異常關(guān)閉有個reset,但reset一般是10054(Connection reset by peer)的錯誤,那么10053與10054的區(qū)別在哪里。要搞清楚問題也不難,重現(xiàn)場景抓包分析。
以下是修改上面的cs程序,在client發(fā)送的1字節(jié)包后,立即crash,這導(dǎo)致的問題是操作系統(tǒng)會立即回收所有資源,包括socket資源。

圖4 10054錯誤client端tcp狀態(tài)流轉(zhuǎn)
可以看到在crash之前這個tcp都是established狀態(tài)。crash之后,client端接收數(shù)據(jù)時會收到10054錯誤,場景重現(xiàn)了,我們再看一下抓包情況

圖5 10054錯誤client端tcp抓包
這個抓包情況跟10053很像,1-7也同10053,在8時,client收到server發(fā)過來的reset,表示當(dāng)前連接被強(qiáng)制復(fù)位了。
對比10053和10054可以發(fā)現(xiàn),如果srv返回fin標(biāo)志后再reset那么對應(yīng)的錯誤就是10053,如果直接reset就是10054錯誤。回過頭來在看參考2中的說法也就有點(diǎn)感覺了。
總結(jié)一下:
1.遇到不了解的問題,google是非常好的方法
2.對于一般問題,重現(xiàn)之很重要,可以反復(fù)發(fā)現(xiàn)問題并驗(yàn)證問題。自己寫程序或者搭環(huán)境盡量重現(xiàn)。
3.網(wǎng)絡(luò)問題抓包是利器,包括各種工具的使用netstat wireshark ping traceroute等。
4.多重問題對比其中的差異,這里對比10053錯誤和10054錯誤。
5.理論基礎(chǔ)要搭好,本次問題主要是tcp的異常斷開問題,熟悉tcp斷開的半關(guān)閉和復(fù)位邏輯,不過理論還是理論,同樣是復(fù)位在不同場景下的錯誤碼不同。并且實(shí)現(xiàn)上也跟具體的操作系統(tǒng)相關(guān)。
6.實(shí)際工作中,10053錯誤時,用戶主要是處于透明代理情況,那么這一般是又有用戶所在的代理服務(wù)器異常關(guān)閉導(dǎo)致的,可能跟我們的離線文件私有協(xié)議被用戶所在的代理服務(wù)器拒絕掉導(dǎo)致的。
7.回過頭來在看一開始的解釋,所謂軟件原因造成的連接終端,就是本例子中,server端在shoutdown本方向傳輸時,立即關(guān)閉了socket,導(dǎo)致本應(yīng)該等待對方發(fā)送fin來完全結(jié)束的正常邏輯被打破,編程單方向強(qiáng)制中止本次tcp,導(dǎo)致client端之后向上報錯,就是所謂的10053錯誤了,這里的軟件就是server端的那個程序。(不過也有種說法是,客戶端發(fā)送錯誤數(shù)據(jù),導(dǎo)致server端保護(hù)機(jī)制而強(qiáng)制關(guān)閉)
參考:
- http://www.chilkatsoft.com/p/p_299.asp
- http://bbs.csdn.net/topics/360024280#post-361829232
- 《TCP/IP詳解(卷一)》18章 TCP連接的建立和中止
|