A. 網路 之 三次握手&四次揮手 介紹
要了解三次握手&四次揮手的過程,就需要對TCP的報頭以及有限狀態機的概念有所了解,本文將介紹TCP報頭的欄位的含義,以及有限狀態機各個狀態的意義,最後對三次握手和四次揮手的過程做介紹
TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連接的、可靠的、基於位元組流的傳輸層通信協議,由IETF的RFC 793定義。在簡化的計算機網路OSI模型中,它完成第四層傳輸層所指定的功能,用戶數據報協議(UDP)是同一層內另一個重要的傳輸協議。在網際網路協議族(Internet protocol suite)中,TCP層是位於IP層之上,應用層之下的中間層。不同主機的應用層之間經常需要可靠的、像管道一樣的連接,但是IP層不提供這樣的流機制,而是提供不可靠的包交換。
這里將介紹TCP報頭的特性以及TCP報頭各個欄位的含義
.工作在傳輸層面向連接協議
.全雙工協議
.半關閉
.錯誤檢查
.將數據打包成段,排序
.確認機制
.數據恢復,重傳
.流量控制,滑動窗口
.擁塞控制,慢啟動和擁塞避免演算法
.源埠、目標埠 :計算機上的進程要和其他進程通信是要通過計算機埠的,而一個計算機埠某個時刻只能被一個進程佔用,所以通過指定源埠和目標埠,就可以知道是哪兩個進程需要通信。源埠、目標埠是用16位表示的,可推算計算機的埠個數為2^16個
. 序列號 :表示本報文段所發送數據的第一個位元組的編號。在TCP連接中所傳送的位元組流的每一個位元組都會按順序編號。由於序列號由32位表示,所以每2^32個位元組,就會出現序列號回繞,再次從0 開始
. 確認號 :表示接收方期望收到發送方下一個報文段的第一個位元組數據的編號。也就是告訴發送發:我希望你(指發送方)下次發送的數據的第一個位元組數據的編號是這個確認號
. 數據偏移 :表示TCP報文段的首部長度,共4位,由於TCP首部包含一個長度可變的選項部分,需要指定這個TCP報文段到底有多長。它指出TCP 報文段的數據起始處距離TCP 報文段的起始處有多遠。該欄位的單位是32位(即4個位元組為計算單位),4位二進制最大表示15,所以數據偏移也就是TCP首部最大60位元組
. URG :表示本報文段中發送的數據是否包含緊急數據。後面的緊急指針欄位(urgent pointer)只有當URG=1時才有效
. ACK :表示是否前面的確認號欄位是否有效。ACK=1,表示有效。只有當ACK=1時,前面的確認號欄位才有效。TCP規定,連接建立後,ACK必須為1,帶ACK標志的TCP報文段稱為確認報文段
. PSH :提示接收端應用程序應該立即從TCP接收緩沖區中讀走數據,為接收後續數據騰出空間。如果為1,則表示對方應當立即把數據提交給上層應用,而不是緩存起來,如果應用程序不將接收到的數據讀走,就會一直停留在TCP接收緩沖區中
. RST :如果收到一個RST=1的報文,說明與主機的連接出現了嚴重錯誤(如主機崩潰),必須釋放連接,然後再重新建立連接。或者說明上次發送給主機的數據有問題,主機拒絕響應,帶RST標志的TCP報文段稱為復位報文段
. SYN :在建立連接時使用,用來同步序號。當SYN=1,ACK=0時,表示這是一個請求建立連接的報文段;當SYN=1,ACK=1時,表示對方同意建立連接。SYN=1,說明這是一個請求建立連接或同意建立連接的報文。只有在前兩次握手中SYN才置為1,帶SYN標志的TCP報文段稱為同步報文段
. FIN :表示通知對方本端要關閉連接了,標記數據是否發送完畢。如果FIN=1,即告訴對方:「我的數據已經發送完畢,你可以釋放連接了」,帶FIN標志的TCP報文段稱為結束報文段
. 窗口大小 :表示現在充許對方發送的數據量,也就是告訴對方,從本報文段的確認號開始允許對方發送的數據量
. 校驗和 :提供額外的可靠性
. 緊急指針 :標記緊急數據在數據欄位中的位置
. 選項部分 :其最大長度可根據TCP首部長度進行推算。TCP首部長度用4位表示,選項部分最長為:(2^4-1)*4-20=40位元組
常見選項 :
.最大報文段長度:MaxiumSegment Size,MSS
.窗口擴大:Windows Scaling
.時間戳:Timestamps
.a 最大報文段長度
指明自己期望對方發送TCP報文段時那個數據欄位的長度。默認是536位元組。數據欄位的長度加上TCP首部的長度才等於整個TCP報文段的長度。MSS不宜設的太大也不宜設的太小。若選擇太小,極端情況下,TCP報文段只含有1位元組數據,在IP層傳輸的數據報的開銷至少有40位元組(包括TCP報文段的首部和IP數據報的首部)。這樣,網路的利用率就不會超過1/41。若TCP報文段非常長,那麼在IP層傳輸時就有可能要分解成多個短數據報片。在終點要把收到的各個短數據報片裝配成原來的TCP報文段。當傳輸出錯時還要進行重傳,這些也都會使開銷增大。因此MSS應盡可能大,只要在IP層傳輸時不需要再分片就行。在連接建立過程中,雙方都把自己能夠支持的MSS接入這一欄位。MSS只出現在SYN報文中。即:MSS出現在SYN=1的報文段中
.b 窗口擴大
為了擴大窗口,由於TCP首部的窗口大小欄位長度是16位,所以其表示的最大數是65535。但是隨著時延和帶寬比較大的通信產
生(如衛星通信),需要更大的窗口來滿足性能和吞吐率,所以產生了這個窗口擴大選項
.c 時間戳
可以用來計算RTT(往返時間),發送方發送TCP報文時,把當前的時間值放入時間戳欄位,接收方收到後發送確認報文時,把這個時間戳欄位的值復制到確認報文中,當發送方收到確認報文後即可計算出RTT。也可以用來防止回繞序號PAWS,也可以說可以用來區分相同序列號的不同報文。因為序列號用32為表示,每2^32個序列號就會產生回繞,那麼使用時間戳欄位就很容易區分相同序列號的不同報文
2.3 TCP協議PORT
.傳輸層通過port號,確定應用層協議
.Port number:
. tcp :0-65535,傳輸控制協議,面向連接的協議;通信前需要建立虛擬鏈路;結束後拆除鏈路.
. udp :0-65535,User Datagram Protocol,無連接的協議.
. IANA :互聯網數字分配機構(負責域名,數字資源,協議分配)
0-1023:系統埠或特權埠(僅管理員可用) ,眾所周知,永久的分配給固定的系統應用使用,22/tcp(ssh), 80/tcp(http), 443/tcp(https)
1024-49151:用戶埠或注冊埠,但要求並不嚴格,分配給程序注冊為某應用使用,1433/tcp(SqlServer),1521/tcp(oracle),
3306/tcp(mysql),11211/tcp/udp(memcached)
49152-65535:動態埠或私有埠,客戶端程序隨機使用的埠
其范圍的定義:/proc/sys/net/ipv4/ip_local_port_range
有限狀態機,(英語:Finite-state machine, FSM),又稱有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。
常見的計算機就是使用有限狀態機作為計算模型的:對於內存的不同狀態,CPU通過讀取內存值進行計算,更新內存中的狀態。CPU還通過消息匯流排接受外部輸入設備(如鍵盤、滑鼠)的指令,計算後更改內存中的狀態,計算結果輸出到外部顯示設備(如顯示器),以及持久化存儲在硬碟。
TCP協議也存在有限狀態機的概念,TCP 協議的操作可以使用一個具有 11 種狀態的有限狀態機來表示
.CLOSED 沒有任何連接狀態
.LISTEN 偵聽狀態,等待來自遠方TCP埠的連接請求
.SYN-SENT 在發送連接請求後,等待對方確認
.SYN-RECEIVED 在收到和發送一個連接請求後,等待對方確認
.ESTABLISHED 代表傳輸連接建立,雙方進入數據傳送狀態
.FIN-WAIT-1 主動關閉,主機已發送關閉連接請求,等待對方確認
.FIN-WAIT-2 主動關閉,主機已收到對方關閉傳輸連接確認,等待對方發送關閉傳輸連接請求
.TIME-WAIT 完成雙向傳輸連接關閉,等待所有分組消失
.CLOSE-WAIT 被動關閉,收到對方發來的關閉連接請求,並已確認
.LAST-ACK 被動關閉,等待最後一個關閉傳輸連接確認,並等待所有分組消失
.CLOSING 雙方同時嘗試關閉傳輸連接,等待對方確認
.客戶端通過connect系統調用主動與伺服器建立連接connect系統調用首先給伺服器發送一個同步報文段,使連接轉移到SYN_SENT狀態。
.此後connect系統調用可能因為如下兩個原因失敗返回:
.1、如果connect連接的目標埠不存在(未被任何進程監聽),或者該埠仍被處於TIME_WAIT狀態的連接所佔用(見後文),則伺服器將給客戶端發送一個復位報文段,connect調用失敗。
.2、如果目標埠存在,但connect在超時時間內未收到伺服器的確認報文段,則connect調用失敗。
.connect調用失敗將使連接立即返回到初始的CLOSED狀態。如果客戶端成功收到伺服器的同步報文段和確認,則connect調用成功返回,連接轉移至ESTABLISHED狀態
.當客戶端執行主動關閉時,它將向伺服器發送一個結束報文段FIN,同時連接進入FIN_WAIT_1狀態。若此時客戶端收到伺服器專門用於確認目的的確認報文段,則連接轉移至FIN_WAIT_2狀態。當客戶端處於FIN_WAIT_2狀態時,伺服器處於CLOSE_WAIT狀態,這一對狀態是可能發生半關閉的狀態。此時如果伺服器也關閉連接(發送結束報文段),則客戶端將給予確認並進入TIME_WAIT狀態
.客戶端從FIN_WAIT_1狀態可能直接進入TIME_WAIT狀態(不經過FIN_WAIT_2狀態),前提是處於FIN_WAIT_1狀態的伺服器直接收到帶確認信息的結束報文段(而不是先收到確認報文段,再收到結束報文段)
注意,客戶端先發送一個FIN給服務端,自己進入了FIN_WAIT_1狀態,這時等待接收服務端的報文,該報文會有三種可能:
a 只有服務端的ACK,只收到伺服器的ACK,客戶端會進入FIN_WAIT_2狀態,後續當收到服務端的FIN時,回應發送一個ACK,會進入到TIME_WAIT狀態,這個狀態會持續2MSL(TCP報文段在網路中的最大生存時間,RFC 1122標準的建議值是2min).客戶端等待2MSL,是為了當最後一個ACK丟失時,可以再發送一次。因為服務端在等待超時後會再發送一個FIN給客戶端,進而客戶端知道ACK已丟失
b 只有服務端的FIN,回應一個ACK給服務端,進入CLOSING狀態,然後接收到服務端的ACK時,進入TIME_WAIT狀態
c 同時收到服務端的ACK和FIN,直接進入TIME_WAIT狀態
.收到伺服器ACK後,客戶端處於FIN_WAIT_2狀態,此時需要等待伺服器發送結束報文段,才能轉移至TIME_WAIT狀態,否則它將一直停留在這個狀態。如果不是為了在半關閉狀態下繼續接收數據,連接長時間地停留在FIN_WAIT_2狀態並無益處。連接停留在FIN_WAIT_2狀態的情況可能發生在:客戶端執行半關閉後,未等伺服器關閉連接就強行退出了。此時客戶端連接由內核來接管,可稱之為孤兒連接(和孤兒進程類似)。
.Linux為了防止孤兒連接長時間存留在內核中,定義了兩個內核參數:
./proc/sys/net/ipv4/tcp_max_orphans 指定內核能接管的孤兒連接數目
./proc/sys/net/ipv4/tcp_fin_timeout指定孤兒連接在內核中生存的時間
TCP協議中的三次握手和四次揮手
客戶機端的三次握手和四次揮手
伺服器端的三次握手和四次揮手
1 client 首先發送一個連接試探,此時ACK=0,表示確認號無效,SYN=1表示這是一個請求連接或連接接受報文,同時表示這個數據包不攜帶數據,seq=x表示此時client自己數據的初始序號是x,這時候client進入syn_sent狀態,表示客戶端等等伺服器的回復
2 server 監聽到連接請求報文後,如同意建立連接,則向client發送確認,將TCP報文首部的SYN和ACK都置為1,因為client上一個請求連接的報文中seq=x,所以伺服器端這次就發ack=x+1,表示伺服器端希望客戶端下一個報文段的第一個數據位元組序號是x+1,同時表示x為止的所有數據都已經正確收到了,其中,此時伺服器端發送seq=y表示server自己的初始序號是y,這時伺服器進入了SYN_RCVD狀態,表示伺服器已經收到了客戶端的請求,等待client的確認。
3 client收到確認後還要再次給伺服器端發送確認,同時攜帶要發給server的數據。ACK=1表示確認號ack=y+1有效,client這時的序號seq為x+1
一旦client確認後,這個TCP連接的client 和 server 都直接進入到established狀態,可以發起http請求了
4.2 四次揮手詳解
第一次揮手:client向server,發送FIN報文段,表示關閉數據傳送,此時ACK=0,seq=u,表示客戶端此時數據的報文序號是u,此時,client進入FIN_WAIT_1狀態,表示沒有數據要傳輸了
第二次揮手:server收到FIN報文段後進入CLOSE_WAIT狀態(被動關閉),然後發送ACK確認,表示同意你關閉請求了,主機到主機的數據鏈路關閉,同時發送seq=v,表示此時server端的數據包位元組序號是v,ack=u+1,表示希望client發送的下一個包的序號是u+1,表示確認了序號u之前的包都已經收到,客戶端收到server的ACK報文後,進入FIN_WAIT_2狀態
第三次揮手:server等待client發送完數據,發送FIN=1,ACK=1到client請求關閉,server進入LAST_ACK狀態。此時發送的seq有變化,因為上一個ACK的後server端可能又發送了一些數據,說以數據位元組序號發送了變化,為w,但是ack還是保持不變
第四次揮手:client收到server發送的FIN後,回復ACK確認到server,client進入TIME_WAIT狀態。發送ack=w+1,表示希望伺服器下個發送的報文的位元組序號是w+1,確認了伺服器之前發送的w位元組都已經正確收到,發送seq=u+1表示當前client的位元組序號是u+1.server收到client的ACK後就關閉連接了,狀態為CLOSED。client等待2MSL,仍然沒有收到server的回復,說明server已經正常關閉了,client關閉連接。
其中,MSL(Maximum Segment Lifetime):報文最大生存時間,是任何報文段被丟棄前在網路內的最長時間。當client回復server的FIN後,等待(2-4分鍾),即使兩端的應用程序結束。
TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態的原因是如果client直接進入CLOSED狀態,由於IP協議不可靠性或網路問題,導致client最後發出的ACK報文未被server接收到,那麼server在超時後繼續向client重新發送FIN,而client已經關閉,那麼找不到向client發送FIN的連接,server這時收到RST並把錯誤報告給高層,不符合TCP協議的可靠性特點。如果client直接進入CLOSED狀態,而server還有數據滯留在網路中,當有一個新連接的埠和原來server的相同,那麼當原來滯留的數據到達後,client認為這些數據是新連接的。等待2MSL確保本次連接所有數據消失。
當客戶端等待2MSL後伺服器端沒有再次發送確認的報文後,client認為該次斷開連接已經正常結束,client進入closed狀態。四次揮手正式結束
B. 計算機網路中的三次握手問題
第一步應用層的程序都開始傳輸數據了,很明顯三次握手已經完成了
C. 三次握手機制用於解決什麼
用於解決網路中出現重復請求報文的問題。
第一次:首先A發送一個(SYN)到B,意思是A要和B建立連接進行通信,如果是只有一次握手,這樣肯定是不行的,A壓根都不知道B是不是收到了這個請求。
第二次:B收到A要建立連接的請求之後,發送一個確認(SYN+ACK)給A,意思是收到A的消息了,B這里也是通的,表示可以建立連接。如果只有兩次通信,這時候B不確定A是否收到了確認消息,有可能這個確認消息由於某些原因丟了。
第三次:A如果收到了B的確認消息之後,再發出一個確認(ACK)消息,意思是告訴B,這邊是通的,然後A和B就可以建立連接相互通信了。
(3)握手計算機網路擴展閱讀:
注意事項:
剛接觸網路編程時,感覺網路連接的建立、網路數據的收發、網路連接的斷開這些操作僅僅是調用幾個socket AIP就可以搞定的事情,跟網路中講述的TCP三次握手等內容完全扯不上關系。
listen函數:內核為任何一個給定的套接字維護兩個隊列 1.未完成連接狀態(客戶端發送的第一個SYN已經到伺服器,伺服器等待TCP三次握手完成,這些套接字處於SYN_RCVD狀態)。
D. 計算機網路中的「三次握手」是什麼
TCP握手協議
在TCP/IP協議中,TCP協議提供可靠的連接服務,採用三次握手建立一個連接。
第一次握手:建立連接時,客戶端發送syn包(syn=j)到伺服器,並進入SYN_SEND狀態,等待伺服器確認;
SYN: 同步序列編號(Synchronize Sequence Numbers)
第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;
第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手。
完成三次握手,客戶端與伺服器開始傳送數據,在上述過程中,還有一些重要的概念:
未連接隊列:在三次握手協議中,伺服器維護一個未連接隊列,該隊列為每個客戶端的SYN包(syn=j)開設一個條目,該條目表明伺服器已收到SYN包,並向客戶發出確認,正在等待客戶的確認包。這些條目所標識的連接在伺服器處於Syn_RECV狀態,當伺服器收到客戶的確認包時,刪除該條目,伺服器進入ESTABLISHED狀態。
Backlog參數:表示未連接隊列的最大容納數目。
SYN-ACK 重傳次數 伺服器發送完SYN-ACK包,如果未收到客戶確認包,伺服器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次重傳,如果重傳次數超過系統規定的最大重傳次數,系統將該連接信息從半連接隊列中刪除。注意,每次重傳等待的時間不一定相同。
半連接存活時間:是指半連接隊列的條目存活的最長時間,也即服務從收到SYN包到確認這個報文無效的最長時間,該時間值是所有重傳請求包的最長等待時間總和。有時我們也稱半連接存活時間為Timeout時間、SYN_RECV存活時間。
E. 計算機網路自學筆記:TCP
如果你在學習這門課程,僅僅為了理解網路工作原理,那麼只要了解TCP是可靠傳輸,數據傳輸丟失時會重傳就可以了。如果你還要參加研究生考試或者公司面試等,那麼下面內容很有可能成為考查的知識點,主要的重點是序號/確認號的編碼、超時定時器的設置、可靠傳輸和連接的管理。
1 TCP連接
TCP面向連接,在一個應用進程開始向另一個應用進程發送數據之前,這兩個進程必須先相互「握手」,即它們必須相互發送某些預備報文段,以建立連接。連接的實質是雙方都初始化與連接相關的發送/接收緩沖區,以及許多TCP狀態變數。
這種「連接」不是一條如電話網路中端到端的電路,因為它們的狀態完全保留在兩個端系統中。
TCP連接提供的是全雙工服務 ,應用層數據就可在從進程B流向進程A的同時,也從進程A流向進程B。
TCP連接也總是點對點的 ,即在單個發送方與單個接收方之間建立連接。
一個客戶機進程向伺服器進程發送數據時,客戶機進程通過套接字傳遞數據流。
客戶機操作系統中運行的 TCP軟體模塊首先將這些數據放到該連接的發送緩存里 ,然後會不時地從發送緩存里取出一塊數據發送。
TCP可從緩存中取出並放入報文段中發送的數據量受限於最大報文段長MSS,通常由最大鏈路層幀長度來決定(也就是底層的通信鏈路決定)。 例如一個鏈路層幀的最大長度1500位元組,除去數據報頭部長度20位元組,TCP報文段的頭部長度20位元組,MSS為1460位元組。
報文段被往下傳給網路層,網路層將其封裝在網路層IP數據報中。然後這些數據報被發送到網路中。
當TCP在另一端接收到一個報文段後,該報文段的數據就被放人該連接的接收緩存中。應用程序從接收緩存中讀取數據流(注意是應用程序來讀,不是操作系統推送)。
TCP連接的每一端都有各自的發送緩存和接收緩存。
因此TCP連接的組成包括:主機上的緩存、控制變數和與一個進程連接的套接字變數名,以及另一台主機上的一套緩存、控制變數和與一個進程連接的套接字。
在這兩台主機之間的路由器、交換機中,沒有為該連接分配任何緩存和控制變數。
2報文段結構
TCP報文段由首部欄位和一個數據欄位組成。數據欄位包含有應用層數據。
由於MSS限制了報文段數據欄位的最大長度。當TCP發送一個大文件時,TCP通常是將文件劃分成長度為MSS的若干塊。
TCP報文段的結構。
首部包括源埠號和目的埠號,它用於多路復用/多路分解來自或送至上層應用的數據。另外,TCP首部也包括校驗和欄位。報文段首部還包含下列欄位:
32比特的序號欄位和32比特的確認號欄位。這些欄位被TCP發送方和接收方用來實現可靠數據傳輸服務。
16比特的接收窗口欄位,該欄位用於流量控制。該欄位用於指示接收方能夠接受的位元組數量。
4比特的首部長度欄位,該欄位指示以32比特的字為單位的TCP首部長度。一般TCP首部的長度就是20位元組。
可選與變長的選項欄位,該欄位用於當發送方與接收方協商最大報文段長度,或在高速網路環境下用作窗口調節因子時使用。
標志欄位ACK比特用於指示確認欄位中的ACK值的有效性,即該報文段包括一個對已被成功接收報文段的確認。 SYN和FIN比特用於連接建立和拆除。 PSH、URG和緊急指針欄位通常沒有使用。
•序號和確認號
TCP報文段首部兩個最重要的欄位是序號欄位和確認號欄位。
TCP把數據看成一個無結構的但是有序的位元組流。TCP序號是建立在傳送的位元組流之上,而不是建立在傳送的報文段的序列之上。
一個報文段的序號是該報文段首位元組在位元組流中的編號。
例如,假設主機A上的一個進程想通過一條TCP連接向主機B上的一個進程發送一個數據流。主機A中的TCP將對數據流中的每一個位元組進行編號。假定數據流由一個包含4500位元組的文件組成(可以理解為應用程序調用send函數傳遞過來的數據長度),MSS為1000位元組(鏈路層一次能夠傳輸的位元組數),如果主機決定數據流的首位元組編號是7。TCP模塊將為該數據流構建5個報文段(也就是分5個IP數據報)。第一個報文段的序號被賦為7;第二個報文段的序號被賦為1007,第三個報文段的序號被賦為2007,以此類推。前面4個報文段的長度是1000,最後一個是500。
確認號要比序號難理解一些。前面講過,TCP是全雙工的,因此主機A在向主機B發送數據的同時,也可能接收來自主機B的數據。從主機B到達的每個報文段中的序號欄位包含了從B流向A的數據的起始位置。 因此主機B填充進報文段的確認號是主機B期望從主機A收到的下一報文段首位元組的序號。
假設主機B已收到了來自主機A編號為7-1006的所有位元組,同時假設它要發送一個報文段給主機A。主機B等待主機A的數據流中位元組1007及後續所有位元組。所以,主機B會在它發往主機A的報文段的確認號欄位中填上1007。
再舉一個例子,假設主機B已收到一個來自主機A的包含位元組7-1006的報文段,以及另一個包含位元組2007-3006的報文段。由於某種原因,主機A還沒有收到位元組1007-2006的報文段。
在這個例子中,主機A為了重組主機B的數據流,仍在等待位元組1007。因此,A在收到包含位元組2007-3006的報文段時,將會又一次在確認號欄位中包含1007。 因為TCP只確認數據流中至第一個丟失報文段之前的位元組數據,所以TCP被稱為是採用累積確認。
TCP的實現有兩個基本的選擇:
1接收方立即丟棄失序報文段;
2接收方保留失序的位元組,並等待缺少的位元組以填補該間隔。
一條TCP連接的雙方均可隨機地選擇初始序號。 這樣做可以減少將那些仍在網路中的來自兩台主機之間先前連接的報文段,誤認為是新建連接所產生的有效報文段的可能性。
•例子telnet
Telnet由是一個用於遠程登錄的應用層協議。它運行在TCP之上,被設計成可在任意一對主機之間工作。
假設主機A發起一個與主機B的Telnet會話。因為是主機A發起該會話,因此主機A被標記為客戶機,主機B被標記為伺服器。用戶鍵入的每個字元(在客戶機端)都會被發送至遠程主機。遠程主機收到後會復制一個相同的字元發回客戶機,並顯示在Telnet用戶的屏幕上。這種「回顯」用於確保由用戶發送的字元已經被遠程主機收到並處理。因此,在從用戶擊鍵到字元顯示在用戶屏幕上之間的這段時間內,每個字元在網路中傳輸了兩次。
現在假設用戶輸入了一個字元「C」,假設客戶機和伺服器的起始序號分別是42和79。前面講過,一個報文段的序號就是該報文段數據欄位首位元組的序號。因此,客戶機發送的第一個報文段的序號為42,伺服器發送的第一個報文段的序號為79。前面講過,確認號就是主機期待的數據的下一個位元組序號。在TCP連接建立後但沒有發送任何數據之前,客戶機等待位元組79,而伺服器等待位元組42。
如圖所示,共發了3個報文段。第一個報文段是由客戶機發往伺服器,其數據欄位里包含一位元組的字元「C」的ASCII碼,其序號欄位里是42。另外,由於客戶機還沒有接收到來自伺服器的任何數據,因此該報文段中的確認號欄位里是79。
第二個報文段是由伺服器發往客戶機。它有兩個目的:第一個目的是為伺服器所收到的數據提供確認。伺服器通過在確認號欄位中填入43,告訴客戶機它已經成功地收到位元組42及以前的所有位元組,現在正等待著位元組43的出現。第二個目的是回顯字元「C」。因此,在第二個報文段的數據欄位里填入的是字元「C」的ASCII碼,第二個報文段的序號為79,它是該TCP連接上從伺服器到客戶機的數據流的起始序號,也是伺服器要發送的第一個位元組的數據。
這里客戶機到伺服器的數據的確認被裝載在一個伺服器到客戶機的數據的報文段中,這種確認被稱為是捎帶確認.
第三個報文段是從客戶機發往伺服器的。它的唯一目的是確認已從伺服器收到的數據。
3往返時延的估計與超時
TCP如同前面所講的rdt協議一樣,採用超時/重傳機制來處理報文段的丟失問題。最重要的一個問題就是超時間隔長度的設置。顯然,超時間隔必須大於TCP連接的往返時延RTT,即從一個報文段發出到收到其確認時。否則會造成不必要的重傳。
•估計往返時延
TCP估計發送方與接收方之間的往返時延是通過採集報文段的樣本RTT來實現的,就是從某報文段被發出到對該報文段的確認被收到之間的時間長度。
也就是說TCP為一個已發送的但目前尚未被確認的報文段估計sampleRTT,從而產生一個接近每個RTT的采樣值。但是,TCP不會為重傳的報文段計算RTT。
為了估計一個典型的RTT,採取了某種對RTT取平均值的辦法。TCP據下列公式來更新
EstimatedRTT=(1-)*EstimatedRTT+*SampleRTT
即估計RTT的新值是由以前估計的RTT值與sampleRTT新值加權組合而成的。
參考值是a=0.125,因此是一個加權平均值。顯然這個加權平均對最新樣本賦予的權值
要大於對老樣本賦予的權值。因為越新的樣本能更好地反映出網路當前的擁塞情況。從統計學觀點來講,這種平均被稱為指數加權移動平均
除了估算RTT外,還需要測量RTT的變化,RTT偏差的程度,因為直接使用平均值設置計時器會有問題(太靈敏)。
DevRTT=(1-β)*DevRTT+β*|SampleRTT-EstimatedRTT|
RTT偏差也使用了指數加權移動平均。B取值0.25.
•設置和管理重傳超時間隔
假設已經得到了估計RTT值和RTT偏差值,那麼TCP超時間隔應該用什麼值呢?TCP將超時間隔設置成大於等於估計RTT值和4倍的RTT偏差值,否則將造成不必要的重傳。但是超時間隔也不應該比估計RTT值大太多,否則當報文段丟失時,TCP不能很快地重傳該報文段,從而將給上層應用帶來很大的數據傳輸時延。因此,要求將超時間隔設為估計RTT值加上一定餘量。當估計RTT值波動較大時,這個余最應該大些;當波動比較小時,這個餘量應該小些。因此使用4倍的偏差值來設置重傳時間。
TimeoutInterval=EstimatedRTT+4*DevRTT
4可信數據傳輸
網際網路的網路層服務是不可靠的。IP不保證數據報的交付,不保證數據報的按序交付,也不保證數據報中數據的完整性。
TCP在IP不可靠的盡力而為服務基礎上建立了一種可靠數據傳輸服務。
TCP提供可靠數據傳輸的方法涉及前面學過的許多原理。
TCP採用流水線協議、累計確認。
TCP推薦的定時器管理過程使用單一的重傳定時器,即使有多個已發送但還未被確認的報文段也一樣。重傳由超時和多個ACK觸發。
在TCP發送方有3種與發送和重傳有關的主要事件:從上層應用程序接收數據,定時器超時和收到確認ACK。
從上層應用程序接收數據。一旦這個事件發生,TCP就從應用程序接收數據,將數據封裝在一個報文段中,並將該報文段交給IP。注意到每一個報文段都包含一個序號,這個序號就是該報文段第一個數據位元組的位元組流編號。如果定時器還沒有計時,則當報文段被傳給IP時,TCP就啟動一個該定時器。
第二個事件是超時。TCP通過重傳引起超時的報文段來響應超時事件。然後TCP重啟定時器。
第三個事件是一個來自接收方的確認報文段(ACK)。當該事件發生時,TCP將ACK的值y與變數SendBase(發送窗口的基地址)進行比較。TCP狀態變數SendBase是最早未被確認的位元組的序號。就是指接收方已正確按序接收到數據的最後一個位元組的序號。TCP採用累積確認,所以y確認了位元組編號在y之前的所有位元組都已經收到。如果Y>SendBase,則該ACK是在確認一個或多個先前未被確認的報文段。因此發送方更新其SendBase變數,相當於發送窗口向前移動。
另外,如果當前有未被確認的報文段,TCP還要重新啟動定時器。
快速重傳
超時觸發重傳存在的另一個問題是超時周期可能相對較長。當一個報文段丟失時,這種長超時周期迫使發送方等待很長時間才重傳丟失的分組,因而增加了端到端時延。所以通常發送方可在超時事件發生之前通過觀察冗餘ACK來檢測丟包情況。
冗餘ACK就是接收方再次確認某個報文段的ACK,而發送方先前已經收到對該報文段的確認。
當TCP接收方收到一個序號比所期望的序號大的報文段時,它認為檢測到了數據流中的一個間隔,即有報文段丟失。這個間隔可能是由於在網路中報文段丟失或重新排序造成的。因為TCP使用累計確認,所以接收方不向發送方發回否定確認,而是對最後一個正確接收報文段進行重復確認(即產生一個冗餘ACK)
如果TCP發送方接收到對相同報文段的3個冗餘ACK.它就認為跟在這個已被確認過3次的報文段之後的報文段已經丟失。一旦收到3個冗餘ACK,TCP就執行快速重傳 ,
即在該報文段的定時器過期之前重傳丟失的報文段。
5流量控制
前面講過,一條TCP連接雙方的主機都為該連接設置了接收緩存。當該TCP連接收到正確、按序的位元組後,它就將數據放入接收緩存。相關聯的應用進程會從該緩存中讀取數據,但沒必要數據剛一到達就立即讀取。事實上,接收方應用也許正忙於其他任務,甚至要過很長時間後才去讀取該數據。如果應用程序讀取數據時相當緩慢,而發送方發送數據太多、太快,會很容易使這個連接的接收緩存溢出。
TCP為應用程序提供了流量控制服務以消除發送方導致接收方緩存溢出的可能性。因此,可以說 流量控制是一個速度匹配服務,即發送方的發送速率與接收方應用程序的讀速率相匹配。
前面提到過,TCP發送方也可能因為IP網路的擁塞而被限制,這種形式的發送方的控制被稱為擁塞控制(congestioncontrol)。
TCP通過讓接收方維護一個稱為接收窗口的變數來提供流量控制。接收窗口用於告訴發送方,該接收方還有多少可用的緩存空間。因為TCP是全雙工通信,在連接兩端的發送方都各自維護一個接收窗口變數。 主機把當前的空閑接收緩存大小值放入它發給對方主機的報文段接收窗口欄位中,通知對方它在該連接的緩存中還有多少可用空間。
6 TCP連接管理
客戶機中的TCP會用以下方式與伺服器建立一條TCP連接:
第一步: 客戶機端首先向伺服器發送一個SNY比特被置為1報文段。該報文段中不包含應用層數據,這個特殊報文段被稱為SYN報文段。另外,客戶機會選擇一個起始序號,並將其放置到報文段的序號欄位中。為了避免某些安全性攻擊,這里一般隨機選擇序號。
第二步: 一旦包含TCP報文段的用戶數據報到達伺服器主機,伺服器會從該數據報中提取出TCPSYN報文段,為該TCP連接分配TCP緩存和控制變數,並向客戶機TCP發送允許連接的報文段。這個允許連接的報文段還是不包含應用層數據。但是,在報文段的首部卻包含3個重要的信息。
首先,SYN比特被置為1。其次,該 TCP報文段首部的確認號欄位被置為客戶端序號+1最後,伺服器選擇自己的初始序號,並將其放置到TCP報文段首部的序號欄位中。 這個允許連接的報文段實際上表明了:「我收到了你要求建立連接的、帶有初始序號的分組。我同意建立該連接,我自己的初始序號是XX」。這個同意連接的報文段通常被稱為SYN+ACK報文段。
第三步: 在收到SYN+ACK報文段後,客戶機也要給該連接分配緩存和控制變數。客戶機主機還會向伺服器發送另外一個報文段,這個報文段對伺服器允許連接的報文段進行了確認。因為連接已經建立了,所以該ACK比特被置為1,稱為ACK報文段,可以攜帶數據。
一旦以上3步完成,客戶機和伺服器就可以相互發送含有數據的報文段了。
為了建立連接,在兩台主機之間發送了3個分組,這種連接建立過程通常被稱為 三次握手(SNY、SYN+ACK、ACK,ACK報文段可以攜帶數據) 。這個過程發生在客戶機connect()伺服器,伺服器accept()客戶連接的階段。
假設客戶機應用程序決定要關閉該連接。(注意,伺服器也能選擇關閉該連接)客戶機發送一個FIN比特被置為1的TCP報文段,並進人FINWAIT1狀態。
當處在FINWAIT1狀態時,客戶機TCP等待一個來自伺服器的帶有ACK確認信息的TCP報文段。當它收到該報文段時,客戶機TCP進入FINWAIT2狀態。
當處在FINWAIT2狀態時,客戶機等待來自伺服器的FIN比特被置為1的另一個報文段,
收到該報文段後,客戶機TCP對伺服器的報文段進行ACK確認,並進入TIME_WAIT狀態。TIME_WAIT狀態使得TCP客戶機重傳最終確認報文,以防該ACK丟失。在TIME_WAIT狀態中所消耗的時間是與具體實現有關的,一般是30秒或更多時間。
經過等待後,連接正式關閉,客戶機端所有與連接有關的資源將被釋放。 因此TCP連接的關閉需要客戶端和伺服器端互相交換連接關閉的FIN、ACK置位報文段。
F. http和https的區別http與TCP/IP區別http/TCP三次握手四次揮手
https, 全稱Hyper Text Transfer Protocol Secure,相比http,多了一個secure,這一個secure是怎麼來的呢?這是由TLS(SSL)提供的,這個又是什麼呢?估計你也不想知道。大概就是一個叫openSSL的library提供的。https和http都屬於application layer,基於TCP(以及UDP)協議,但是又完全不一樣。TCP用的port是80, https用的是443(值得一提的是,google發明了一個新的協議,叫QUIC,並不基於TCP,用的port也是443, 同樣是用來給https的。谷歌好牛逼啊。)總體來說,https和http類似,但是比http安全。
http預設工作在TCP協議80埠(需要國內備案),用戶訪問網站http://打頭的都是標准http服務,http所封裝的信息都是明文的,通過抓包工具可以分析其信息內容,如果這些信息內容包含你的銀行卡賬號、密碼,你肯定無法接受這種服務,那有沒有可以加密這些敏感信息的服務呢?那就是https!
https是http運行在SSL/TLS之上,SSL/TLS運行在TCP之上。所有傳輸的內容都經過加密,加密採用對稱加密,但對稱加密的密鑰用伺服器方的證書進行了非對稱加密。此外客戶端可以驗證伺服器端的身份,如果配置了客戶端驗證,伺服器方也可以驗證客戶端的身份。
https預設工作在tcp協議443埠,它的工作流程一般如以下方式:
1、完成tcp三次同步握手;
2、客戶端驗證伺服器數字證書,通過,進入步驟3;
3、DH演算法協商對稱加密演算法的密鑰、hash演算法的密鑰;
4、SSL安全加密隧道協商完成;
5、網頁以加密的方式傳輸,用協商的對稱加密演算法和密鑰加密,保證數據機密性;用協商的hash演算法進行數據完整性保護,保證數據不被篡改。
附:https一般使用的加密與hash演算法如下:
非對稱加密演算法:RSA,DSA/DSS
對稱加密演算法:AES,RC4,3DES
hash演算法:MD5,SHA1,SHA256
如果https是網銀服務,以上SSL安全隧道成功建立才會要求用戶輸入賬戶信息,賬戶信息是在安全隧道里傳輸,所以不會泄密!
TPC/IP協議是傳輸層協議,主要解決數據如何在網路中傳輸,而HTTP是應用層協議,主要解決如何包裝數據。Web使用HTTP協議作應用層協議,以封裝HTTP 文本信息,然後使用TCP/IP做傳輸層協議將它發到網路上。
下面的圖表試圖顯示不同的TCP/IP和其他的協議在最初OSI(Open System Interconnect)模型中的位置:
CA證書是什麼?
CA(Certificate Authority)是負責管理和簽發證書的第三方權威機構,是所有行業和公眾都信任的、認可的。
CA證書,就是CA頒發的證書,可用於驗證網站是否可信(針對HTTPS)、驗證某文件是否可信(是否被篡改)等,也可以用一個證書來證明另一個證書是真實可信,最頂級的證書稱為根證書。除了根證書(自己證明自己是可靠),其它證書都要依靠上一級的證書,來證明自己。
https大致過程:
1、建立伺服器443埠連接 ;
2、SSL握手:隨機數,證書,密鑰,加密演算法;
3、發送加密請求 ;
4、發送加密響應;
5、關閉SSL;
6、關閉TCP.
SSL握手大致過程:
1、客戶端發送隨機數1,支持的加密方法(如RSA公鑰加密);
2、服務端發送隨機數2,和伺服器公鑰,並確認加密方法;
3、客戶端發送用伺服器公鑰加密的隨機數3;
4、伺服器用私鑰解密這個隨機數3,用加密方法計算生成對稱加密的密鑰給客戶端;
5、接下來的報文都用雙方協定好的加密方法和密鑰,進行加密.
1、TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的,即發送數據之前不需要建立連接
2、TCP提供可靠的服務。也就是說,通過TCP連接傳送的數據,無差錯,不丟失,不重復,且按序到達;UDP盡最大努力交付,即不保證可靠交付
3、TCP面向位元組流,實際上是TCP把數據看成一連串無結構的位元組流(流模式);UDP是面向報文的(報文模式),UDP沒有擁塞控制,因此網路出現擁塞不會使源主機的發送速率降低(對實時應用很有用,如IP電話,實時視頻會議等)
4、每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通信
5、TCP要求系統資源較多,UDP較少。TCP首部開銷20位元組;UDP的首部開銷小,只有8個位元組
SYN:同步序列編號; ACK=1: 確認序號 ; FIN附加標記的報文段(FIN表示英文finish)
一個TCP連接必須要經過三次「對話」才能建立起來,其中的過程非常復雜,只簡單的 描述下這三次對話的簡單過程:主機A向主機B發出連接請求數據包:「我想給你發數據,可以嗎?」,這是第一次對話;主機B向主機A發送同意連接和要求同步 (同步就是兩台主機一個在發送,一個在接收,協調工作)的數據包:「可以,你什麼時候發?」,這是第二次對話;主機A再發出一個數據包確認主機B的要求同 步:「我現在就發,你接著吧!」,這是第三次對話。三次「對話」的目的是使數據包的發送和接收同步,經過三次「對話」之後,主機A才向主機B正式發送數據。
為什麼需要「三次握手」?
在謝希仁著《計算機網路》第四版中講「三次握手」的目的是「 為了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤 」。在另一部經典的《計算機網路》一書中講「三次握手」的目的是為了解決「網路中存在延遲的重復分組」的問題。這兩種不一樣的表述其實闡明的是同一個問題。
謝希仁版《計算機網路》中的例子是這樣的,「已失效的連接請求報文段」的產生在這樣一種情況下:client發出的第一個連接請求報文段並沒有丟失,而是在某個網路結點長時間的滯留了,以致延誤到連接釋放以後的某個時間才到達server。 本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段後,就誤認為是client再次發出的一個新的連接請求。於是就向client發出確認報文段,同意建立連接。假設不採用「三次握手」,那麼只要server發出確認,新的連接就建立了。由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據。但server卻以為新的運輸連接已經建立,並一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。 採用「三次握手」的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連接。」。 主要目的防止server端一直等待,浪費資源。
為什麼需要「四次揮手」?
可能有人會有疑問,在tcp連接握手時為何ACK是和SYN一起發送,這里ACK卻沒有和FIN一起發送呢。原因是 因為tcp是全雙工模式,接收到FIN時意味將沒有數據再發來,但是還是可以繼續發送數據。
握手,揮手過程中各狀態介紹:
3次握手過程狀態:
LISTEN: 這個也是非常容易理解的一個狀態,表示伺服器端的某個SOCKET處於監聽狀態,可以接受連接了。
SYN_SENT : 當客戶端SOCKET執行CONNECT連接時,它首先發送SYN報文,因此也隨即它會進入到了SYN_SENT狀態,並等待服務端的發送三次握手中的第2個報文。SYN_SENT狀態表示客戶端已發送SYN報文。(發送端)
SYN_RCVD : 這個狀態與SYN_SENT遙想呼應這個狀態表示接受到了SYN報文,在正常情況下,這個狀態是伺服器端的SOCKET在建立TCP連接時的三次握手會話過程中的一個中間狀態,很短暫,基本上用netstat你是很難看到這種狀態的,除非你特意寫了一個客戶端測試程序,故意將三次TCP握手過程中最後一個 ACK報文不予發送。因此這種狀態時,當收到客戶端的ACK報文後,它會進入到ESTABLISHED狀態。(伺服器端)
ESTABLISHED :這個容易理解了,表示連接已經建立了。
4次揮手過程狀態:(可參考下圖):
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連接,但另外還告訴對方,我暫時還有點數據需要傳送給你(ACK信息),稍後再關閉連接。(主動方)
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可用狀態了。(被動方)
CLOSED: 表示連接中斷。
TCP的具體狀態圖可參考:
G. 計算機網路三次握手四次揮手用文字簡單論述一下
哈哈,不錯
H. 網路技術中的握手,是什麼意思
握手在現實世界中是兩個人都伸出手握在一塊。
所以引申到網路協議中就是,需要建立鏈接的兩台設備 A 和 B,A 發送數據給 B,B 隨之回復數據給 A。這叫做「兩次握手」
握手本質就是數據發送給對方,學習網路死扣這些字眼用處不大。
I. 在計算機網路中,TCP終止採用幾次握手
三次握手:
1.發出請求
2.同意,同時發出ack
3.確認,同時發送ack