TCP(Transmission Control Protocol) 傳輸控制協議
?
TCP是主機對主機層的傳輸控制協議,提供可靠的連接服務,采用三次握手確認建立一個連接:
位碼即tcp標志位,有6種標示:SYN(synchronous建立聯機) ACK(acknowledgement 確認) PSH(push傳送) FIN(finish結束) RST(reset重置) URG(urgent緊急)
Sequence number(順序號碼) Acknowledge number(確認號碼)
第一次握手:主機A發送位碼為syn=1,隨機產生seq number=1234567的數據包到服務器,主機B由SYN=1知道,A要求建立聯機;
第二次握手:主機B收到請求后要確認聯機信息,向A發送ack number=(主機A的seq+1),syn=1,ack=1,隨機產生seq=7654321的包
第三次握手:主機A收到后檢查ack number是否正確,即第一次發送的seq number+1,以及位碼ack是否為1,若正確,主機A會再發送ack number=(主機B的seq+1),ack=1,主機B收到后確認seq值與ack=1則連接建立成功。
完成三次握手,主機A與主機B開始傳送數據。
在TCP/IP協議中,TCP協議提供可靠的連接服務,采用三次握手建立一個連接。 ?
第一次握手:建立連接時,客戶端發送syn包(syn=j)到服務器,并進入SYN_SEND狀態,等待服務器確認; ?
第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器 進入SYN_RECV狀態; 第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入 ESTABLISHED狀態,完成三次握手。 完成三次握手,客戶端與服務器開始傳送數據.
?
實例:
?
IP 192.168.1.116.3337 > 192.168.1.123.7788: S 3626544836:3626544836
IP 192.168.1.123.7788 > 192.168.1.116.3337: S 1739326486:1739326486 ack 3626544837
IP 192.168.1.116.3337 > 192.168.1.123.7788: ack 1739326487,ack 1
IP 192.168.1.123.7788 > 192.168.1.116.3337: S 1739326486:1739326486 ack 3626544837
IP 192.168.1.116.3337 > 192.168.1.123.7788: ack 1739326487,ack 1
第一次握手:192.168.1.116發送位碼syn=1,隨機產生seq number=3626544836的數據包到192.168.1.123,192.168.1.123由SYN=1知道192.168.1.116要求建立聯機;
第二次握手:192.168.1.123收到請求后要確認聯機信息,向192.168.1.116發送ack number=3626544837,syn=1,ack=1,隨機產生seq=1739326486的包;
第 三次握手:192.168.1.116收到后檢查ack number是否正確,即第一次發送的seq number+1,以及位碼ack是否為1,若正確,192.168.1.116會再發送ack number=1739326487,ack=1,192.168.1.123收到后確認seq=seq+1,ack=1則連接建立成功。
?
圖解:
一個三次握手的過程(圖1,圖2)
(圖1)
(圖2)
第一次握手的標志位(圖3)
我們可以看到標志位里面只有個同步位,也就是在做請求(SYN)
(圖3)
第二次握手的標志位(圖4)
我們可以看到標志位里面有個確認位和同步位,也就是在做應答(SYN + ACK)
(圖4)
第三次握手的標志位(圖5)
我們可以看到標志位里面只有個確認位,也就是再做再次確認(ACK)
(圖5)
一個完整的三次握手也就是 請求---應答---再次確認
一個三次握手的過程(圖1,圖2)
(圖1)
(圖2)
第一次握手的標志位(圖3)
我們可以看到標志位里面只有個同步位,也就是在做請求(SYN)
(圖3)
第二次握手的標志位(圖4)
我們可以看到標志位里面有個確認位和同步位,也就是在做應答(SYN + ACK)
(圖4)
第三次握手的標志位(圖5)
我們可以看到標志位里面只有個確認位,也就是再做再次確認(ACK)
(圖5)
一個完整的三次握手也就是 請求---應答---再次確認
四次分手:
?
由于
TCP
連接是全雙工的,因此每個方向都必須單獨進行關閉。這個原則是當一方完成它的數據發送任務后就能發送一個
FIN
來終止這個方向的連接。收到一個
?
FIN
只意味著這一方向上沒有數據流動,一個
TCP
連接在收到一個
FIN
后仍能發送數據。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。
?
(
1
)客戶端
A
發送一個
FIN
,用來關閉客戶
A
到服務器
B
的數據傳送(報文段
4
)。
(
2
)服務器
B
收到這個
FIN
,它發回一個
ACK
,確認序號為收到的序號加
1
(報文段
5
)。和
SYN
一樣,一個
FIN
將占用一個序號。
(
3
)服務器
B
關閉與客戶端
A
的連接,發送一個
FIN
給客戶端
A
(報文段
6
)。
(
4
)客戶端
A
發回
ACK
報文確認,并將確認序號設置為收到序號加
1
(報文段
7
)。
?
??????
?
狀態詳解:
?
??????? CLOSED:
?
這個沒什么好說的了,表示初始狀態。
?
?
?
LISTEN:
?
這個也是非常容易理解的一個狀態,表示服務器端的某個SOCKET處于監聽狀態,可以接受連接了。
?
???? SYN_RCVD:
?
這個狀態表示接受到了SYN報文,在正常情況下,這個狀態是服務器端的SOCKET在建立TCP連接時的三次握手會話過程中的一個中間狀態,很短暫,基本上用netstat你是很難看到這種狀態的,除非你特意寫了一個客戶端測試程序,故意將三次TCP握手過程中最后一個ACK報文不予發送。因此這種狀態時,當收到客戶端的ACK報文后,它會進入到ESTABLISHED狀態。
?
SYN_SENT:
?
這個狀態與SYN_RCVD遙想呼應,當客戶端SOCKET執行CONNECT連接時,它首先發送SYN報文,因此也隨即它會進入到了SYN_SENT狀態,并等待服務端的發送三次握手中的第2個報文。SYN_SENT狀態表示客戶端已發送SYN報文。
?
???? ESTABLISHED:
這個容易理解了,表示連接已經建立了。
?
??????? FIN_WAIT_1:
?
這個狀態要好好解釋一下,其實FIN_WAIT_1和FIN_WAIT_2狀態的真正含義都是表示等待對方的FIN報文。而這兩種狀態的區別是:FIN_WAIT_1狀態實際上是當SOCKET在ESTABLISHED狀態時,它想主動關閉連接,向對方發送了FIN報文,此時該SOCKET即進入到FIN_WAIT_1狀態。而當對方回應ACK報文后,則進入到FIN_WAIT_2狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ACK報文,所以FIN_WAIT_1狀態一般是比較難見到的,而FIN_WAIT_2狀態還有時常常可以用netstat看到。
??????? FIN_WAIT_2: 上面已經詳細解釋了這種狀態,實際上FIN_WAIT_2狀態下的SOCKET,表示半連接,也即有一方要求close連接,但另外還告訴對方,我暫時還有點數據需要傳送給你,稍后再關閉連接。
??????? TIME_WAIT:
?
表示收到了對方的FIN報文,并發送出了ACK報文,就等2MSL后即可回到CLOSED可用狀態了。如果FIN_WAIT_1狀態下,收到了對方同時帶FIN標志和ACK標志的報文時,可以直接進入到TIME_WAIT狀態,而無須經過FIN_WAIT_2狀態。
CLOSING:
?
這種狀態比較特殊,實際情況中應該是很少見,屬于一種比較罕見的例外狀態。正常情況下,當你發送FIN報文后,按理來說是應該先收到(或同時收到)對方的ACK報文,再收到對方的FIN報文。但是CLOSING狀態表示你發送FIN報文后,并沒有收到對方的ACK報文,反而卻也收到了對方的FIN報文。什么情況下會出現此種情況呢?其實細想一下,也不難得出結論:那就是如果雙方幾乎在同時close一個SOCKET的話,那么就出現了雙方同時發送FIN報文的情況,也即會出現CLOSING狀態,表示雙方都正在關閉SOCKET連接。
??????? CLOSE_WAIT:
?
這種狀態的含義其實是表示在等待關閉。怎么理解呢?當對方close一個SOCKET后發送FIN報文給自己,你系統毫無疑問地會回應一個ACK報文給對方,此時則進入到CLOSE_WAIT狀態。接下來呢,實際上你真正需要考慮的事情是察看你是否還有數據發送給對方,如果沒有的話,那么你也就可以close這個SOCKET,發送FIN報文給對方,也即關閉連接。所以你在CLOSE_WAIT狀態下,需要完成的事情是等待你去關閉連接。
??????? LAST_ACK:
?
這個狀態還是比較容易好理解的,它是被動關閉一方在發送FIN報文后,最后等待對方的ACK報文。當收到ACK報文后,也即可以進入到CLOSED可用狀態了。
總結:
?
??????? 1
.為什么建立連接協議是三次握手,而關閉連接卻是四次握手呢?
?
這是因為服務端的
LISTEN
狀態下的
SOCKET
當收到
SYN
報文的建連請求后,它可以把
ACK
和
SYN
(
ACK
起應答作用,而
SYN
起同步作用)放在一個報文里來發送。但關閉連接時,當收到對方的
FIN
報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可以未必會馬上會關閉
SOCKET,
也即你可能還需要發送一些數據給對方之后,再發送
FIN
報文給對方來表示你同意現在可以關閉連接了,所以它這里的
ACK
報文和
FIN
報文多數情況下都是分開發送的.
?
2
.為什么
TIME_WAIT
狀態還需要等
2MSL
后才能返回到
CLOSED
狀態?
?
這是因為雖然雙方都同意關閉連接了,而且握手的
4
個報文也都協調和發送完畢,按理可以直接回到
CLOSED
狀態(就好比從
SYN_SEND
狀態到
ESTABLISH
狀態那樣);但是因為我們必須要假想網絡是不可靠的,你無法保證你最后發送的
ACK
報文會一定被對方收到,因此對方處于
LAST_ACK
狀態下的
SOCKET
可能會因為超時未收到
ACK
報文,而重發
FIN
報文,所以這個
TIME_WAIT
狀態的作用就是用來重發可能丟失的
ACK
報文。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
