ESTABLISHED"半連接"的狀態(tài)詳解
所謂半開TCP連接,簡(jiǎn)單地說(shuō)就是發(fā)送了TCP連接請(qǐng)求,但還沒(méi)有得到對(duì)方應(yīng)答的狀態(tài)(實(shí)際上要復(fù)雜些),也就是連接尚未完全建立起來(lái),雙方還無(wú)法進(jìn)行通信交互的狀態(tài)。
? ? 我這里討論的"半連接"是在tcp已經(jīng)建立后,進(jìn)行通訊的過(guò)程中,一方的連接因?yàn)楫惓嗟?,另一方?jīng)]有收到任何數(shù)據(jù)包,仍處于ESTABLISHED的狀態(tài)。
? ? ? 半連接占用了tcp的資源,在大量并發(fā)的網(wǎng)站會(huì)使服務(wù)器資源耗盡而導(dǎo)致服務(wù)器的假死甚至癱瘓。另半連接的狀態(tài)下,tcp協(xié)議棧仍能正常工作,應(yīng)用層的程序不能覺(jué)察。
檢測(cè)半連接的方法,一般使用tcp提供的keepalive的屬性,需要設(shè)置的選項(xiàng)包含;
setsockopt函數(shù)的選項(xiàng),組合使用: SOL_SOCKET, SO_KEEPALIVE IPPROTO_TCP, TCP_KEEPIDLE IPPROTO_TCP, TCP_KEEPINTVL IPPROTO_TCP, TCP_KEEPCNT
當(dāng)tcp協(xié)議棧檢測(cè)到半連接的狀態(tài),會(huì)發(fā)送reset包,關(guān)閉連接,避免產(chǎn)生time_wait的狀態(tài)。
也用在業(yè)務(wù)層發(fā)送心跳包,檢測(cè)半連接,但是一定要有響應(yīng)包,如果超時(shí),就關(guān)閉連接。close會(huì)產(chǎn)生time_wait.
如果只發(fā)送心跳包是沒(méi)法檢測(cè)半連接的,因?yàn)閼?yīng)用層會(huì)把包發(fā)送到tcp的發(fā)送緩沖區(qū),不返回錯(cuò)誤信息。