1 連接狀態(tài)圖

2 建立連接:三次握手,不使用DNS和使用DNS


3 關(guān)閉連接-四次握手
<div align="center"/>

</div>
連接雙方任何一方調(diào)用close()后,連接的兩個傳輸方向都關(guān)閉,不能再發(fā)送數(shù)據(jù)了。如果一方調(diào)用shutdown()則連接處于半關(guān)閉狀態(tài),仍可接收對方發(fā)來的數(shù)據(jù)。
如果出現(xiàn)半關(guān)閉,例如客戶->服務(wù)器方向關(guān)閉。則服務(wù)器還可以發(fā),客戶端還可以收。
協(xié)議規(guī)定主動關(guān)閉一方,進入FIN_WAIT_2->TIME_WAIT,必須等待2MSL(MSL為最大報文段生存時間,LWIP為1分鐘,windows為2分鐘)時間然后才進入CLOSED,刪除TCP控制塊。在2MSL等待時間內(nèi)遲到的報文段將被拋棄。
如果我們在客戶端關(guān)閉一個連接然后又立刻建立連接(使用同一端口號),2MSL時間內(nèi)之前連接的端口號不能使用,即使調(diào)用bind函數(shù)也將返回-1(綁定失?。瑑?nèi)核將自動分配一個新的端口號使用。通常情況下這個我們并不關(guān)心,因為客戶端的端口號我們并不關(guān)心,只要能用就可以。但是如果是服務(wù)器就不一樣了,服務(wù)器的端口一般是固定的,客戶端必須知道服務(wù)器的端口號才能建立連接,所以如果服務(wù)器端主動斷開連接時,就需要注意,或者做一些處理:不讓它等待2MSL后才可以使用,具體做法:使能SO_REUSEPORT(允許重用本地地址),可以通過調(diào)用setsockopt函數(shù)來使能。
2MSL等待的原因:報文段有生存時間,當連接關(guān)閉時,有可能收到遲到的報文段。這時,若立馬就建立新的連接(同一端口),那么新的連接就會接收遲到的報文,誤以為是發(fā)給自己的。另一個原因是可靠的實現(xiàn)全雙工連接的終止。
在FIN_WAIT_2狀態(tài)我們已經(jīng)發(fā)出了FIN,并且另一端也已對它進行確認。除非我們在實行半關(guān)閉,否則將等待另一端的應(yīng)用層意識到它已收到一個文件結(jié)束符說明,并向我們發(fā)一個FIN來關(guān)閉另一方向的連接。只有當另一端的進程完成這個關(guān)閉,我們這端才會從FIN_WAIT_2狀態(tài)進入TIME_WAIT狀態(tài)。這意味著我們這端可能永遠保持這個狀態(tài)(FIN_WAIT_2,如果對方不發(fā)送FIN包)。另一端也將處于CLOSE_WAIT狀態(tài),并一直保持這個狀態(tài)直到應(yīng)用層決定進行關(guān)閉(調(diào)用close然后進入LAST_ACK)。