TCP/IP協議

  TCP是面向鏈接的通訊協議,經過三次握手創建鏈接,通信完成時要拆除鏈接,因爲TCP是面向鏈接的因此只能用於端到端的通信。程序員

       TCP提供的是一種可靠的數據流服務,採用「帶重傳的確定確認」技術來實現傳輸的可靠性。TCP還採用一種稱爲「滑動窗口」的方式進行流量控制,所謂出港口實際表示接收能力,用以限制發送方的發送速度。數據庫

       若是TCP數據包有已經封好的TCP數據包,那麼IP將把他們向「上」傳送到TCP層。TCP將包排序並進行錯誤檢查,同時實現虛電路間的鏈接。TCP數據包中包括序號和確認,因此未按照順序收到的包能夠被排序,而損壞的包能夠被重傳。編程

       TCP將它的信息送到更高層的應用程序,例如Trelnet的服務程序和客戶程序。應用程序輪流將信息送回TCP層,TCP層便將它們向下傳送到IP層,設備驅動程序和物理介質,最後到接收方。windows

       面向鏈接的服務(例如Telnet、Ftp、rlogin、X windows和SMTP)須要高度的可靠性,因此它們使用TCP。DNS在某些狀況下使用TCP(發送和接受域名數據庫),可是用UDP傳送有關單個主機的信息。緩存

一、TCP三次握手

 

  TCP提供面向有鏈接的通訊傳輸。面向有鏈接是指在數據同你新年開始以前先作好兩端之間的準備工做。服務器

       所謂三次握手是指創建一個TCP鏈接時須要客戶端和服務端總共發送三個包以確認鏈接的創建。在socket編程中,這一過程有客戶戶端執行connect來觸發。網絡

       第一次握手:客戶端將標誌位SYN置爲1,隨機產生一個值seq=J,並將該數據包發送給服務器,客戶端進入SYN_SENT狀態,等待服務器端確認。併發

       第二次握手:服務器端收到數據包後由編制爲SYN=1知道客戶端請求創建鏈接,服務器端將標誌位SYN和ACK都置位1,ack=J+1,隨機產生一個值seq=K,並將改數據包發送給客戶端以確認鏈接請求,服務器端進入SYN_RCVD狀態。socket

       第三次握手:客戶端收到確認後,檢查ack是否爲J+1,ACK是否爲1,若是正確則將標誌位ACK置位1,ack=K+1,並將改數據包發送給服務器端,服務器端檢查ack是否爲K+1,ACK是否爲1,若是正確則鏈接創建成功,客戶端和服務器端進入ESTABLISHED狀態,完成三次握手,隨後客戶端與服務端之間能夠開始傳輸數據了。函數

二、 TCP的三次握手的漏洞

  可是在TCP三次握手中有一個缺陷,就是若是咱們利用三次握手的缺陷進行攻擊。這個攻擊就是SYN洪泛攻擊。三次握手中有一個第二次握手,服務端向客戶端應答請求,應答請求時須要客戶端IP的,服務端是須要知道客戶端IP的,攻擊者就僞造這個IP,往服務器端狂發第一次握手的內容,固然第一次握手中的客戶端IP地址是僞造的,從而服務端忙於進行第二次握手可是第二次握手固然沒有結果,因此致使服務端被拖累,死機。

       面對這種攻擊,有如下的解決方案,最好的方案是防火牆。

       無效鏈接監視釋放

       這種方法不停監視全部的鏈接,包括三次握手的,還有握手一次的,反正是全部的,當達到必定閾值是拆除這些鏈接,從而釋放系統資源。這種方法對於全部的鏈接一視同仁,無論是正常仍是工技大額,因此這種方式不推薦。

       延緩TCB分配方法

       通常作完第一次握手以後,服務器就須要爲改請求分配一個TCB(鏈接控制資源),一般這個資源須要200多個字節。延遲TCB的分配,當正常鏈接創建起來後在分配TCB則能夠有效地減輕服務器資源的消耗。

       使用防火牆

       防火牆在確認了鏈接的有效性後,才向內部的服務器(Listener)發起SYN請求

三、TCP四次揮手(分手)

  四次揮手即終止TCP鏈接,就是指斷開一個TCP鏈接時,須要客戶端和服務端總共發送4個包確認鏈接的斷開。在socket編程中,這一過程客戶端或服務端任一方執行close來觸發

       因爲TCP鏈接時全雙工的,所以,每一個方向都必需要單獨進行關閉,這一原則是當一方完成數據發送任務後,發送一個FIIN來終止之一方向的鏈接,收到一個FIN只是意味着這一方向上沒有數據流動了,即不會再收到數據了,可是在這個TCP鏈接上任然可以發送數據,直到這一方向也發送了FIN。首先進行關閉的一方將執行主動關閉,而另外一方則執行被動關閉。

 

一、客戶端進程發出鏈接釋放報文,而且中止發送數據。釋放數據報文首部FIN=1,其序號爲seq=u(等於前面已經傳送過來的數據的最後一個字節的序號加1),此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。TCP規定,FIN報文段即便不攜帶數據也要消耗一個序號。

二、服務器收到鏈接釋放的報文,發出確認報文,ACK=1,ack=u+1,而且帶上字節序列號seq=v,此時,服務器進入CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處於半關閉狀態,及客戶端已經沒有數據要發送了,可是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的 時間。

三、客戶端收到服務器端的確認請求後,此時,客戶端進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文(在這以前還須要接受服務器發送的最後的數據)。

四、服務器將最後的數據發送完畢後,就向客戶端發送鏈接釋放報文,FIN=1,ack=u+1,因爲在半關閉狀態,服務器極可能有發送一些數據,假定此時的序列號爲sqp=w,此時,服務器就進入LAST-ACK(最後確認)狀態,等待客戶端的確認。

五、客戶端收到服務器的鏈接釋放報文後,必須發出確認,ACK=1,ack=w+1,而本身的徐磊好是seq=u+1,此時,客戶端就進入2*MSL(最長報文段壽命)的時間後,當客戶端撤銷相應的TCB後,才進入CLOSED狀態。

服務器只要收到客戶端發出的確認,當即進入CLOSED狀態。一樣,撤銷TCB後,就結束了此次的TCP鏈接。能夠看到,服務器結束TCP鏈接的書簡要比客戶端早一些。

四、TCP的通信原理

⑴、Socket套接字

  Socket的願意是「插座」,在計算機通訊領域,scoket被翻譯成「套接字,它是計算機之間進行通訊的一種約定或一種方式」。經過socket這種約定,一臺計算機能夠接收其餘計算機的數據,也能夠向其餘計算機發送數據。TCP用主機的IP地址加上主機的端口號做爲TCP鏈接的端點,這種端點就叫作套接字(scoket)。

       區分不一樣應用程序進程間的網絡通訊和鏈接,主要有3個參數:通訊的目的IP地址、使用的傳輸層協議(TCP或UDP)和使用的端口號。經過將3個參數結合起來,與一個「插座」socket綁定,應用層就能夠和傳輸層套接字接口區分來自不一樣應用進程或網絡鏈接的通訊,實現數據傳輸的併發服務。

       套接字對是一個定義該鏈接的兩個端點的四元組:本地IP地址、本地TCP端口號、外地IP地址、外地TCP端口號。套接字對惟一即是一個網絡上的每一個TCP鏈接。

⑵、TCP緩衝區

  每一個TCP的socket的內核中都有一個發送緩衝區和一個接受緩衝區。如今咱們假設用write()方法發送數據,使用read()方法接受數據。

 

 

 

  Write()並不當即向網絡中傳輸數據,而是先將數據寫入緩衝區中,再由TCP協議將數據從緩衝區發送到目標機器。一旦將數據寫入緩衝區,函數就能夠成功返回,無論它們有沒有到達目標機器,也無論它們合適發送到網絡,這些都是TCP協議負責的事情。

       TCP協議獨立於write()函數,數據有可能剛被寫入緩衝區就被髮送到網絡,也可能在緩衝區不斷積壓,屢次寫入的數據被一次性發送到網絡,這就取決於當時的網絡狀況、當前線程是否空閒等諸多因素,不有程序員控制。

       Read()也是如此,也從輸入緩衝區中讀取數據,而不是直接從網絡中讀取。

       總的來講,I/O緩衝區自在每一個TCP套接字中單獨存在;I/O緩衝區在建立套接字時自動生成。

TCP的可靠性性

  在TCP中,當發送端的數據到達接收主機時,接收端主句會返回一個已收到消息的通知。這個消息叫作確認應答(ACK)。當發送端將數據發出以後會等待對端的確認應答。若是有確認應答,說明數據已經成功到達對端。反之,則數據丟失的可能性很大。

       在必定時間內沒有等待到確認應答,發送端就能夠認爲數據已經丟失,並進行重發。由此,即便產生了丟包,仍然能保證書可以到達對端,實現可靠傳輸。

       爲收到確認應答並不意味着數據必定丟失。也有多是數據對方已經收到,只是返回的確認應答在途中丟失。這種狀況也會致使發送端誤覺得數據沒有到達目的地而重發數據。

       此外,也有可能由於一些其餘緣由致使確認應答延遲到達,在源主句重發數據之後纔到達的狀況也家常便飯。此時,源主機只要按照機制重發數據便可。

       對於目標主機來講,反覆收到相同的數據是不可取的。爲了對上層應用提供可靠的傳輸,目標主機必須放棄重複的數據包。位置咱們引進了序列號。、

       序列號是按照順序給發送數據的每個字節(8位字節)都標上號碼的編號。接受端查詢接收數據TCP首部中的序列號和數據的長度,將本身下一步應該接收的序列號做爲確認應答返回。經過序列號和確認應答號,TCP能都識別是否已經接收數據,又可以判斷是否須要接收,從而實現可靠傳輸。

TCP的滑動窗口

  發送方和接收方都會維護一個數據幀的序列,這個序列被稱爲窗口。發送方的窗口大小由接收方確認,目的是控制發送速度,一面接收方的緩存不夠大致使溢出,同時控制流量也能夠避免網絡擁塞。

       在TCP的可靠性的圖中,咱們能夠看到,發送方每發送一個數據接收方就要給發送發一個ACK對這個數據進行確認。只有接受了這個確認數據之後發送發才能傳輸下個數據。

       存在的問題:若是窗口太小,當傳輸比較大的數據的時候須要不停的對數據進行確認這個時候就會形成很大的延遲。

       若是窗口過大。咱們假設發送發一次發送100個數據,可是接收方只能處理50個數據,這樣每次都只能處理50個數據進行確認。發送方下一次仍是要發送100個數據,可是接收方仍是隻能處理50個數據。這樣就避免了沒必要要的數據來擁塞咱們的鏈路。

       所以,咱們引入了滑動窗口。滑動窗口通俗來說就是一種流量控制技術。

       它本質上市描述接收方的TCP數據緩衝區大小的數據,發送方根據這個數據來計算本身嘴都能發送多長的數據,若是發送方收到接收方的窗口大小爲0的TCP數報,那麼發送方就中止發送數據,等到接收方發送窗口大小不爲0的數據報的到來。

 

  首先是第一次發送數據,這個時候的窗口大小是根據鏈路寬帶的大小來決定的。咱們假設這個時候窗口的大小是3。這個時候接收方收到數據之後會對數據進行確認告訴發送方我下次但願收到的數據是多少。這裏咱們看到接收方發送的ACK=3(這是發送方發送序列2的回答確認,下一次接收方但願接受到的是3序列信號)。這個時候發送方收到這個數據之後就知道我第一次發送的3個數據對方只收到2個。就知道第3個數據對方沒有收到。下次在發送的時候就從第3個數據開始發。

       此時窗口大小變成2。

       因而發送方發送2個數據。看到接收方發送的ACK 是5就表示它下一次但願收到的數據是5,發送方就知道我剛纔發送的2個數據對方收了,這個時候發送第5個數據。

       這就是滑動窗口的工做機制,當鏈路變好了或者變差了這個窗口還會發生變化,並非第一次協商好之後就永遠不變了。

       因此滑動窗口協議,是TCP使用的一種流量控制方法。改協議容許發送方在中止並等待確認前能夠連續發送多個分組。因爲發送方沒必要每2發一個分組就停下來等待確認,所以該協議能夠加速數據的傳輸。

       只有在接受窗口向前滑動時(與此同時也發送確認),發送窗口才有可能向前滑動。

       收發兩端的窗口按照以上規律不斷向前滑動,所以這種協議又稱爲滑動窗口協議。

相關文章
相關標籤/搜索