TCP(Transfer Control Protocol)傳輸控制協議,是一種面向連接的保證可靠傳輸的協議。
在TCP/IP協議中
-
IP層主要負責網絡主機的定位,數據傳輸的路口,有IP地址可以唯一確定Internet上單一臺主機
-
TCP層提供面向應用的數據傳輸機制
發送方和接收方的成對的兩個socket之間必須建立連接, 通過TCP協議得到的是一個順序的無差錯的數據流
TCP是一個基於連接的協議,能夠提供兩臺計算機之間的可靠的數據流
UDP
UDP(User Datagram Protocol)用戶數據報協議,是一種無連接的協議 。
UDP是發送一種稱爲數據報的獨立數據包的協議,該協議並不保證數據報是否能正確的到達目的地,它是一個非面向連接的協議。
每個數據報都是一個獨立的信息,包括完整的源地址或目的地址,他在網絡上以任何可能的路徑轉往目的地,因此能否到達目的地,到達時間以及內容的正確性都不能保證。
TCP&&UDP
-
TCP它是一個面向連接的傳輸協議,它在socket之間進行數據傳輸之前必然要先建立連接 。
UDP的每個數據報中都給出了完整的地址信息,在傳輸時無需建立發送方和接收方的連接。
-
TCP是一個可靠的協議,它保證接收方完全正確的獲取發送方所發的全部數據。
UDP是一個不可靠的協議,他無法保證發送方的數據是否完全正確的被接收方接受,發送方的數據並不一定 以相同的次序到達接收方
-
UDP的傳輸效率大於TCP。
-
TCP傳輸數據時沒有大小限制,一旦連接建立起來,雙方的socket的就可以按統一的格式傳輸大量的數據。
UDP傳輸數據時是有大小限制的,每個數據報必須限定在64KB之間。
TCP的三次握手和四次揮手
SYN(synchronous建立聯機)
ACK(acknowledgement 確認)
FIN(finish結束)
Sequence number(順序號碼)
Acknowledge number(確認號碼)
三次握手
TCP是一個面向連接的協議,在正式發收數據前,必須和對方建立可靠的連接,而一個TCP連接必須經過三次握手才能建立起來。
-
第一次握手:建立連接時,Client發出SYN包(SYN=1,隨機產生一個seq=j)到Server,並進入SYN_SEND狀態,等待Server確認。
-
第二次握手:Server收到SYN包,確認Client的SYN,知道Client請求建立連接,將ACK置爲1(ACK=1,ack=j+1),同時自己也發送一個SYN包(SYN=1,seq=k),即SYN+ACK包,此時服務端B進入SYN_RECV狀態。
-
第三次握手:Client收到Server的SYN+ACK包,檢驗ACK是否爲1,ack是否爲j+1,正確則向Server發送確認包ACK(ACK=1,ack=k+1),Server確認ACK與ack,正確則建立連接成功,Client和Server進入ESTABLISHED狀態,完成三次握手。
三次握手的特點:沒有應用層的數據
爲什麼會採用三次握手
採用三次握手是:爲了防止失效的連接請求報文段突然又傳送到server,因而產生錯誤。
失效的連接請求報文段:client發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到某個時間纔到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段後,就誤認爲是client再次發出的一個新的連接請求。於是就向client發出確認報文段,同意建立連接。由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據。但server卻以爲新的運輸連接已經建立,並一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。
若將三次握手改爲兩次握手會怎麼樣?把三次握手改成僅需要兩次握手,死鎖是可能發生的。假定C給S發送一個連接請求分組,S收到了這個分組,併發送了確認應答分組。按照兩次握手的協定,S認爲連接已經成功地建立了,可以開始發送數據分組。可是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S是否已準備好,不知道S建立什麼樣的序列號,C甚至懷疑S是否收到自己的連接請求分組。在這種情況下,C認爲連接還未建立成功,將忽略S發來的任何數據分組,只等待連接確認應答分組。而S在發出的分組超時後,重複發送同樣的分組。這樣就形成了死鎖
四次揮手
TCP連接是全雙工的,每個方向都必須單獨進行關閉。當一方完成它的數據發送任務後就能發送一個FIN來終止這個方向的連接,收到一個FIN只意味着這個方向上沒有數據流動,即不會再收到數據了,但在這個TCP連接上仍能發送數據。首先關閉的一方將執行主動關閉,而另一方執行被動關閉。
-
Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT狀態
-
Server收到FIN後,發送一個ACK給Client,確認序號爲收到序號+1,Server進入CLOSE_WAIT狀態
-
Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態
-
Client收到FIN後,進入TIME_WAIT狀態,接着發送一個ACK給Server,確認序號爲收到序號+1,Server進入CLOSED狀態,完成四次揮手。
爲什麼握手三次,而揮手要四次
這是因爲服務端的LISTEN狀態下的SOCKET當收到SYN報文的建連請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裏來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可以未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的
爲什麼TIME_WAIT狀態還需要等2MSL後才能返回到CLOSED狀態?
這是因爲雖然雙方都同意關閉連接了,而且握手的4個報文也都協調和發送完畢,按理可以直接回到CLOSED狀態(就好比從SYN_SEND狀態到ESTABLISH狀態那樣);但是因爲我們必須要假想網絡是不可靠的,你無法保證你最後發送的ACK報文會一定被對方收到,因此對方處於LAST_ACK狀態下的SOCKET可能會因爲超時未收到ACK報文,而重發FIN報文,所以這個TIME_WAIT狀態的作用就是用來重發可能丟失的ACK報文
DDOS攻擊:
客戶端不斷的向服務端發送連接請求,但又不同意建立連接。
第一步:客戶端向服務器端發送連接請求數據包(1)
第二步:服務器向客戶端回覆連接請求數據包(2),然後服務器等待客戶端發送tcp/ip鏈接的第三步數據包(3)
第三步:如果客戶端不向服務器端發送最後一個數據包(3),則服務器須等待30s到2min中才能將此鏈接進行關閉。當大量的請求只進行到第二步,而不進行第三步,服務器又大量的資源等待第三個數據包。則造成DDos攻擊。
DDOS預防(沒有根治的辦法,除非不使用TCP/IP連接)
1. 關閉不必要的服務
2. 限制同時打開SYN的半連接數目
3. 設置防火牆
4. 縮短服務器等待的時長