tcp每傳送乙個報文段,就啟動乙個定時器,如果在定時器超時之後還沒有收到ack確認,就重傳該報文。 如圖所示,資料報由a的緩衝區發往b,b在收到資料報以後,回發乙個ack確認包給a,之後a將該資料報從緩衝區釋放。因此,該資料報會一直快取在a的緩衝區,直到乙個ack確認為止。
在tcp/ip協議中,tcp協議提供可靠的面向連線的服務;三次握手(建立連線)和四次揮手(關閉連線);使用滑動視窗機制進行流量控制;
三次握手的詳細**
所謂三次握手(three-way handshake),是指建立乙個tcp連線時,需要客戶端和伺服器總共傳送3個包。如圖1所示。
圖1 三次握手建立tcp連線的各狀態
(1)第一次握手:建立連線時,客戶端a傳送syn包[syn=1,seq=x]到伺服器b,並進入syn_send狀態,等待伺服器b確認。
(2)第二次握手:伺服器b收到syn包,必須確認客戶a的syn,同時自己也傳送乙個syn包,即syn+ack包[syn=1,ack=1,seq=y,ack=x+1],此時伺服器b進入syn_recv狀態。
(3)第三次握手:客戶端a收到伺服器b的syn+ack包,向伺服器b傳送確認包ack[ack=1,seq=x+1,ack=y+1],此包傳送完畢,客戶端a和伺服器b進入established狀態,完成三次握手。 完成三次握手,客戶端與伺服器開始傳送資料。
三次握手完成後,客戶端和伺服器就建立了tcp連線。這時可以呼叫accept函式獲得此連線。三次握手的目的是連線伺服器指定埠,建立tcp連線,並同步連線雙方的序列號和確認號並交換tcp 視窗大小資訊。在socket程式設計中,客戶端執行connect()時,將會觸發三次握手。
四次揮手的詳細**
tcp的連線的拆除需要傳送四個包,因此稱為四次揮手(four-way handshake)。客戶端或伺服器均可主動發起揮手動作,在socket程式設計中,任何一方執行close()操作即可產生揮手操作。由於tcp連線是全雙工的,因此每個方向都必須單獨進行關閉。這個原則是當一方完成它的資料傳送任務後就能傳送乙個fin來終止這個方向的連線。收到乙個fin只意味著這一方向上沒有資料流動,乙個tcp連線在收到乙個fin後仍能傳送資料。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。tcp要保證在所有可能的情況下使得所有的資料都能夠被投遞,當你關閉乙個socket時,主動關閉一端的socket將進入time_wait狀態,而被動關閉一方則轉入closed狀態 ,這能夠保證所有的資料都被傳輸。
圖2 四次揮手關閉tcp連線的各狀態
(1)首先a b端的tcp程序都處於established狀態, 當a的應用程式傳送完報文段,就會去主動關閉連線。a會停止傳送報文段(但是還會接收),並向b傳送[fin = 1,seq=u]資料,之後進入fin-wait-1狀態;
(2)b接收到a傳送的請求之後,會通知應用程序,a已經不再傳送資料,同時b會向a傳送ack確認資料[ack=1,seq=v,ack=u+1 ],b進入close-wait狀態,a接收到b傳送的資料之後,a進入fin-wait-2狀態;此時a到b方的連線已經關閉了(即半連線狀態)。
(3)當b的應用程序發現自己也沒有資料需要傳送,b應用程序就會發出被動關閉的請求,b此時向a傳送[fin=1,ack=1,seq=w,ack=u+1]資料,並且進入last-ack狀態;
(4)a接收到b傳送的資料之後,向b傳送ack確認資料[ack =1,seq=u+1,ack=w+1],進入time-wait狀態,等待2msl之後正常關閉連線進入closed狀態;b接收到a傳送的確認之後進入closed狀態。b到a方的連線關閉!至此,tcp連線才真正全部關閉!
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報文。
3.tcp報文段
tcp報文段也分為首部和資料兩部分,首部預設情況下一般是20位元組長度,但在一些需求情況下,會使用「可選字段」,這時,首部長度會有所增加。
tcp首部報文資訊中,有乙個狀態控制碼(code,control flag),也叫標誌位欄位(u、a、p、r、s、f):佔6位元。各位元的含義如下:
urg:緊急位元(urgent)。當urg=1時,表明緊急指標字段有效,代表該封包為緊急封包。它告訴系統此報文段中有緊急資料,應盡快傳送(相當於高優先順序的資料), 且上圖中的 urgent pointer 欄位也會被啟用。
ack:確認位元(acknowledge)。只有當ack=1時確認號字段才有效,代表這個封包為確認封包。當ack=0時,確認號無效。
psh:(push function)。若為1時,代表要求對方立即傳送緩衝區內的其他對應封包,而無需等緩衝滿了才送。
rst:復位位元(reset) 。當rst=1時,表明tcp連線**現嚴重差錯(如由於主機崩潰或其他原因),必須釋放連線,然後再重新建立運輸連線。
syn:同步位元(synchronous)。syn置為1,就表示這是乙個連線請求或連線接受報文,通常帶有 syn 標誌的封包表示『主動』要連線到對方的意思。
fin:終止位元(final)。用來釋放乙個連線。當fin=1時,表明此報文段的傳送端的資料已傳送完畢,並要求釋放運輸連線。
*傳輸資料過程*tcp報文的首部格式中確認號的計算:
確認號是期望收到對方下乙個報文段的第乙個資料位元組的序號。
序列號等於前乙個報文段的序列號與前乙個報文段中資料位元組的數量之和。
4.在已經成功建立連線的tcp連線,在以下四種情況時會導致tcp產生嚴重錯誤,傳送rst包:
1、埠未開啟
2、請求超時
3、提前關閉
4、在乙個已關閉的socket上收到資料
TCP IP協議原理
tcp協議原理 tcp每傳送乙個報文段,就啟動乙個定時器,如果在定時器超時之後還沒有收到ack確認,就重傳該報文。如圖所示,資料報由a的緩衝區發往b,b在收到資料報以後,回發乙個ack確認包給a,之後a將該資料報從緩衝區釋放。因此,該資料報會一直快取在a的緩衝區,直到乙個ack確認為止。在tcp i...
FTP協議原理以及TCP IP協議
檔案傳輸協議 ftp利用 tcpftp 協議占用了兩個 tcp埠,ftp伺服器監聽 21號埠,準備接受使用者的連線請求。當使用者訪問 ftp伺服器時便主動與伺服器的 2120 號埠主動發出建立資料連線的請求,檔案傳輸完成後資料連線隨之釋放。在客戶端看來,這種處理方式被叫做 被動式 ftp windo...
TCP IP協議原理解析
我算是半路出家的程式設計師吧,剛畢業的時候不知道做什麼,工作後慶幸遇到了一名好leader,給我指了前端這條路。所以,雖然可以完成工作,但是對一些基礎知識卻了解的不夠深入透徹,是時候該補補短了。要實現web瀏覽器和伺服器之間的通訊,最基礎的就是http了。開始打算從被稱作聖經的 http權威指南 入...