轉載自https://blog.csdn.net/mary19920410/article/details/58030147
1.TCP報文格式
TCP報頭中的源端口號和目的端口號同IP數據報中的源IP與目的IP唯一確定一條TCP連接
序號(4字節=32位):
37 59 56 75
用來標識TCP發端向TCP收端發送的數據字節流
確認序號(4字節=32位):
由於該報文為SYN報文,ACK標志為0,故沒有確認序號(ACK標志為1時確認序號才有效)TCP協議規定,只有ACK=1時有效,也規定連接建立后所有發送的報文的ACK必須為1
一旦連接建立,該值將始終發送(同ACK標志)
頭部長度:該字段占用4位,用來表示報文首部的長度,單位是4Byte。如:headLen = ((packet[12]>>4)&0x0F)*4;
預留6位:長度為6位,作為保留字段,暫時沒有什么用處。
URG:長1位,表示緊急指針字段有效;
ACK:長1位,置位表示確認號字段有效;TCP協議規定,只有ACK=1時有效,也規定連接建立后所有發送的報文的ACK必須為1
PSH:長1位,表示當前報文需要請求推(push)操作;
RST:長1位,置位表示復位TCP連接;
SYN:長1位,在連接建立時用來同步序號。當SYN=1而ACK=0時,表明這是一個連接請求報文。對方若同意建立連接,則應在響應報文中使SYN=1和ACK=1. 因此,SYN置1就表示這是一個連接請求或連接接受報文。
FIN:長1位,用於釋放TCP連接時標識發送方比特流結束;即完,終結的意思, 用來釋放一個連接。當 FIN = 1時,表明此報文段的發送方的數據已經發送完畢,並要求釋放連接。
窗口大小:長度為16位,2個字節。
校驗和:長度為16位,2個字節。
緊急指針:長度為16位,2個字節。
以上是TCP包頭必須要有的字段,也稱固有字段,長度為20個字節。
2.TCP三次握手
TCP怎樣才能保證可靠的傳輸任務,就是通過三次握手
首先由Client發出請求連接即 SYN=1 ACK=0 (請看頭字段的介紹), TCP規定SYN=1時不能攜帶數據,但要消耗一個序號,因此聲明自己的序號是 seq=x
然后 Server 進行回復確認,即 SYN=1 ACK=1 seq=y, ack=x+1,
再然后 Client 再進行一次確認,但不用SYN 了,這時即為 ACK=1, seq=x+1, ack=y+1.
3.TCP四次揮手
當客戶A 沒有東西要發送時就要釋放 A 這邊的連接,A會發送一個報文(沒有數據),其中 FIN 設置為1, 服務器B收到后會給應用程序一個信,這時A那邊的連接已經關閉,即A不再發送信息(但仍可接收信息)。
A收到B的確認后進入等待狀態,等待B請求釋放連接, B數據發送完成后就向A請求連接釋放,也是用FIN=1 表示, 並且用 ack = u+1(如圖), A收到后回復一個確認信息,並進入 TIME_WAIT 狀態, 等待 2MSL 時間。
為什么要等待呢?
為了這種情況: B向A發送 FIN = 1 的釋放連接請求,但這個報文丟失了, A沒有接到不會發送確認信息, B 超時會重傳,這時A在 WAIT_TIME 還能夠接收到這個請求,這時再回復一個確認就行了。(A收到 FIN = 1 的請求后 WAIT_TIME會重新記時)
另外服務器B存在一個保活狀態,即如果A突然故障死機了,那B那邊的連接資源什么時候能釋放呢? 就是保活時間到了后,B會發送探測信息, 以決定是否釋放連接。
注意:中斷連接端可以是Client端,也可以是Server端。
來個通俗版的解釋:
假設Client端發起中斷連接請求,也就是發送FIN報文。Server端接到FIN報文后,意思是說"我Client端沒有數據要發給你了",但是如果你還有數據沒有發送完成,則不必急着關閉Socket,可以繼續發送數據。所以你先發送ACK,"告訴Client端,你的請求我收到了,但是我還沒准備好,請繼續你等我的消息"。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。當Server端確定數據已發送完成,則向Client端發送FIN報文,"告訴Client端,好了,我這邊數據發完了,准備好關閉連接了"。Client端收到FIN報文后,"就知道可以關閉連接了,但是他還是不相信網絡,怕Server端不知道要關閉,所以發送ACK后進入TIME_WAIT狀態,如果Server端沒有收到ACK則可以重傳。“,Server端收到ACK后,"就知道可以斷開連接了"。Client端等待了2MSL后依然沒有收到回復,則證明Server端已正常關閉,那好,我Client端也可以關閉連接了。Ok,TCP連接就這樣關閉了!(是服務端先關閉,后客戶端關閉)
【問題1】為什么連接的時候是三次握手,關閉的時候卻是四次握手?
答:因為當Server端收到Client端的SYN連接請求報文后,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。
【問題2】為什么TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?
答:雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網絡是不可靠的,有可以最后一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。
整個客戶端所經歷的狀態:
整個服務端經歷的狀態:
栗子1:
TCP鏈接中主動斷開鏈接netstat觀察可能出現的狀態流轉是:CD
A.ESTABLISHED->CLOSE_WAIT->TIME_WAIT->CLOSED
B.ESTABLISHED->TIME_WAIT->CLOSE_WAIT->CLOSED
C.ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
D.ESTABLISHED->FIN_WAIT_1->TIME_WAIT->CLOSED
栗子2:
一條tcp連接,主動關閉的一方不可能出現的連接狀態是()A
A.CLOSE_WAIT
B.FIN_WAIT2
C.TIME_WAIT
D.FIN_WAIT1
4.關於Host文件
host文件一個沒有擴展名的系統文件,其作用就是用來存儲一些常用的網絡域名和與其對應的ip地址,當用戶輸入一個需要登錄的網址時,系統就會先去host文件中查找,如果找到了就立即打開該網址,如果找不到就去DNS域名解析服務器中查找。
參考文檔:http://blog.csdn.net/imilli/article/details/50620104