<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>

您好,歡迎來電子發燒友網! ,新用戶?[免費注冊]

您的位置:電子發燒友網>電子百科>通信技術>數據通信>

基于TCP流協議的數據包通訊

2017年11月27日 14:29 網絡整理 作者: 用戶評論(0

  一、TCP定義

  TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連接的、可靠的、基于字節流的傳輸層通信協議,由IETF的RFC 793定義。在簡化的計算機網絡OSI模型中,它完成第四層傳輸層所指定的功能,用戶數據報協議(UDP)是同一層另一個重要的傳輸協議。在因特網協議族(Internet protocol suite)中,TCP層是位于IP層之上,應用層之下的中間層。不同主機的應用層之間經常需要可靠的、像管道一樣的連接,但是IP層不提供這樣的流機制,而是提供不可靠的包交換。

基于TCP流協議的數據包通訊

  二、TCP可靠性實現

  TCP提供一種面向連接的、可靠的字節流服務。面向連接意味著兩個使用TCP的應用(通常是一個客戶和一個服務器)在彼此交換數據包之前必須先建立一個TCP連接。這一過程與打電話很相似,先撥號振鈴,等待對方摘機說“喂”,然后才說明是誰。在一個TCP連接中,僅有兩方進行彼此通信。廣播和多播不能用于TCP。

  1.應用數據被分割成TCP認為最適合發送的數據塊。這和UDP完全不同,應用程序產生的數據報長度將保持不變。由TCP傳遞給I P的信息單位稱為報文段或段

  2.當TCP發出一個段后,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段。

  3.當TCP收到發自TCP連接另一端的數據,它將發送一個確認。這個確認不是立即發送,通常將推遲幾分之一秒。

  4.TCP將保持它首部和數據的檢驗和。這是一個端到端的檢驗和,目的是檢測數據在傳輸過程中的任何變化。如果收到段的檢驗和有差錯,TCP將丟棄這個報文段和不確認收到此報文段(希望發端超時并重發)。

  5.既然TCP報文段作為IP數據報來傳輸,而IP數據報的到達可能會失序,因此TCP報文段的到達也可能會失序。如果必要,TCP將對收到的數據進行重新排序,將收到的數據以正確的順序交給應用層。

  6.既然I P數據報會發生重復,TCP的接收端必須丟棄重復的數據。

  7.TCP還能提供流量控制。TCP連接的每一方都有固定大小的緩沖空間。TCP的接收端只允許另一端發送接收端緩沖區所能接納的數據。這將防止較快主機致使較慢主機的緩沖區溢出。

  三、TCP連接的建立

  利用TCP傳輸數據前,需要建立tcp連接,tcp連接的建立有3個主要過程,叫做3次握手,具體過程如下圖所示:

基于TCP流協議的數據包通訊

  過程:

  1. 首先客戶端發送一個SYN包給服務器(SYN=1,Seq為主機選擇的這個連接的初始序號),然后等待應答。

  2. 服務器端收到SYN包,回應給客戶端一個ACK =x+1、SYN=1的TCP數據段(ACK表示確認序號有效,即收到上一個包,這里加1并不是ACK的值加1,ACK是一個標志位,這里會變成1,而x+1則是希望收到的下一個包的序列號,這個值放在包的確認序列號字段中,而只有ACK=1時,確認序列號才有效)。

  3. 客戶必須再次回應服務器端一個ACK確認數據段(這里的Seq為x+1)。

  經過上面3個過程就建立了一個tcp連接,接著就可以發送數據了,因為建立連接使用了一個序列號x,所以發送數據的第一個字節序號為x+1。

  注意:這里tcp為應用層提供全雙工服務,意味數據能在兩個方向上獨立地進行傳輸,因此連接的每一段都有各自的傳輸數據序號(對應于上圖中的x和y,這兩個值是沒有必然聯系的)。

  四、TCP協議流的理解

  TCP是流協議,不像UDP那樣sendto發一次消息,另一端必然會收到完整消息,或者沒有收到任何消息。當用TCP send發一次消息的時候,可能另一端在某時刻可能只收到一部分消息,下一時刻才能收到另一部分。那如果一個消息很小,是否可以保證另一端在某時刻能收到這條完整消息?

  調用send后,TCP將數據拷貝到緩沖區。緩沖區內可能不止一條用戶消息。TCP按照一定算法,將緩沖區的數據打包到1-n個TCP報文中,交給IP層發送。TCP報文是TCP協議的最小發送單位,大小應該是可變的,并且丟失的話會重發。并不能保證一個TCP報文中必然包含一條用戶消息的全部,所以即使消息很小,另一端也有可能在某時刻只收到部分

  IP層將TCP報文裝進IP包,然后再交給鏈路層發送以太幀

  理論上IP包的大小應該會選擇比MTU小。一旦IP包比MTU大,意味著網絡上的路由要幫你緩存多個以太幀,拼出IP包后才知道如何路由到下一個節點。向下一節點路由的時候還要再拆分成多個以太幀發送。所以TCP報文應該會比選擇比MTU小。

基于TCP流協議的數據包通訊

  五、基于TCP流協議的數據包通訊

  TCP通訊是流協議,它不像UDP那樣基于包為邊界的通訊方式,TCP流式協議,舉個簡單例子,一端用send 分別發送 100,123,120字節的數據,另一端用recv可以一下子接收到 100+123+120=343字節的數據,或者先接收 3個字節的數據,再接收余下的340字節,不管另一端怎么接收,最終是要接收到343字節的數據。而且TCP保證數據的完整性和順序,也就是兩端是數據同步的,出現任何一點的數據不一致,都會造成TCP連接的失效。

  UDP則跟TCP大不一樣,他是基于包邊界的。所謂的包邊界,就是一端分別發送 100, 123, 120字節的數據,另一端接收到也應該分別是 100,123,120字節數據的三個包,不會出現一端發送100字節的一個數據包,另一端只接收到小于100字節的數據包,或者收到大于100字節的數據包。UDP同時也不保證穩定和順序,如發送端發送100,123,120三個包,接收端可能接收到3個包,也可能只接收到2個包,也可能一個包也收不到,收到的順序不一定是100,123,120,可能是100,120,123,或者123,100,120等。這些TCP和UDP的屬性,大家稍微查查資料就該很清楚。

  UDP的這種特殊通訊方式其實跟網絡底層鏈路層的通訊方式很接近。鏈路層的數據是一個數據包一個數據包的傳輸,并不保證數據能否達到對方,或者按照順序到達對方。UDP只是簡單把鏈路層和IP層的數據加了一層封裝,加了端口用于識別同一個機器的不同進程,UDP數據包的收發方式,只是組合成UDP包之后,簡單的發送到底層網絡了事,至于底層網卡有沒有發成功或者接收成功,它是一概不聞不問的。他的底層處理方式比起 TCP協議來說簡單太多了。

  既然UDP這么好,編程又簡單,可現在網絡中大部分都在使用TCP,一個非常重要的原因就是TCP提供的是可靠傳輸,TCP有一套復雜的底層算法來保證數據的完整和可靠,有這個理由就已經足夠讓TCP在大部分場所比UDP好使了。因為大部分時候,我們在開發網絡通信程序,都希望能隨意的接收和發送任意大小和完整的數據,如果使用UDP,還得自己寫算法來保證數據的順序和完整,整個處理過程就等于實現一個小型的TCP協議。

  一些特殊場所,比如P2P,各種使用P2P的下載軟件如迅雷等,這些軟件和傳統的服務端客戶端模式不大一樣,每個運行軟件的機器既是客戶端也是服務端,而用戶的每個機器可能處于不同的網絡環境中,最典型的就是大部分機器處于NAT中,這樣的環境下,采用UDP是最佳選擇,因為TCP的NAT穿透能力差。

  當然這些軟件使用UDP,他們也必須實現一套算法來保證UDP傳輸的完整和順序。我們在開發TCP程序時候,最先想到的就是 請求-應答模式:就是客戶端發起一個請求,然后服務端接收到請求,進行處理,接著向客戶端應答這個請求。最典型和常用的就是 HTTP協議,我們瀏覽的所有網頁,以及各種玲瑯滿目的網站,這些都是HTTP的功勞,HTTP協議是建立在TCP上的應用層協議,采用就是 請求-應答方式。

  瀏覽器首先發起一個網頁請求的TCP連接,web服務器通過這個TCP連接應答這個網頁,并把網頁內容傳輸給瀏覽器。然后瀏覽器可能關閉這個TCP連接,或者也可能利用這個TCP連接發起另外一個網頁請求。這個請求-應答模式,也是我在使用TCP開發私有協議時候,使用的最多的模式,多得來以至于都忘記其他模式需求的存在了。

非常好我支持^.^

(1) 100%

不好我反對

(0) 0%

( 發表人:姚遠香 )

      發表評論

      用戶評論
      評價:好評中評差評

      發表評論,獲取積分! 請遵守相關規定!

      ?
      亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
      <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
      <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
      <acronym id="s8ci2"></acronym>
      <acronym id="s8ci2"><center id="s8ci2"></center></acronym>