日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

传输层两大协议:TCP与UDP详解(两者的联系与区别)

發布時間:2023/12/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 传输层两大协议:TCP与UDP详解(两者的联系与区别) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、TCP協議

1、TCP協議報文格式

TCP協議報文格式詳解

2、TCP“三次握手”建立連接

位碼即tcp標志位,有6種標示:

SYN(synchronous建立聯機)

ACK(acknowledgement 確認)

PSH(push傳送)

FIN(finish結束)

RST(reset重置)

URG(urgent緊急)

Sequence number(順序號碼)

Acknowledge number(確認號碼)

1)第一次握手:主機A(client)與主機B(server)通信,要建立一個TCP連接。首先B端先運行一個服務器進程,發出一個“被動打開”命令給TCP。之后服務器進程不斷探測端口,看是否有客戶端的連接請求。A端向TCP發送“主動打開”命令,指名要與某個IP地址的某個端口建立TCP連接。第一次主機A向主機B發送連接請求報文,。報文中指明了要鏈接的IP地址和端口號,設置能夠接受的TCP數據段最大值,以及一些用戶數據:SYN=1,ACK=0,發送序號seq=j.

2)第二次握手:A的連接請求到達B之后,B的TCP查看是否有進程在偵聽該端口,如果沒有,就發送RST= 1,拒絕連接,否則將到達的TCP數據段留給“偵聽”進程,,進程將發回一個應答的TCP報文段,其中:SYN=1,ACK=1,確認序號ack = j+1; 同時選一個自己的發送序號 : seq = k 。

3)第三次握手:主機A收到B的確認之后,再向B發送一個TCP報文段,其中:SYN=1;ACK=1;seq=j+1;ack=k+1;
就完成了三次握手。

狀態分析:

(1)第一次握手:Client將標志位SYN置為1,隨機產生一個值seq=J,并將該數據包發送給Server,Client進入SYN_SENT狀態,等待Server確認。

(2)第二次握手:Server收到數據包后由標志位SYN=1知道Client請求建立連接,Server將標志位SYN和ACK都置為1,ack (number )=J+1,隨機產生一個值seq=K,并將該數據包發送給Client以確認連接請求,Server進入SYN_RCVD狀態

(3)第三次握手:Client收到確認后,檢查ack是否為J+1,ACK是否為1,如果正確則將標志位ACK置為1,ack=K+1,并將該數據包發送給Server,Server檢查ack是否為K+1,ACK是否為1,如果正確則連接建立成功,Client和Server進入ESTABLISHED狀態,完成三次握手,隨后Client與Server之間可以開始傳輸數據了。

狀態詳解:

CLOSED: 這個沒什么好說的了,表示初始狀態。

  LISTEN: 這個也是非常容易理解的一個狀態,表示服務器端的某個SOCKET處于監聽狀態,可以接受連接了。

  SYN_RCVD: 這個狀態表示接受到了SYN報文,在正常情況下,這個狀態是服務器端的SOCKET在建立TCP連接時的三次握手會話過程中的一個中間狀態,很短暫,基本 上用netstat你是很難看到這種狀態的,除非你特意寫了一個客戶端測試程序,故意將三次TCP握手過程中最后一個ACK報文不予發送。因此這種狀態 時,當收到客戶端的ACK報文后,它會進入到ESTABLISHED狀態。

  SYN_SENT: 這個狀態與SYN_RCVD遙想呼應,當客戶端SOCKET執行CONNECT連接時,它首先發送SYN報文,因此也隨即它會進入到了SYN_SENT狀態,并等待服務端的發送三次握手中的第2個報文。SYN_SENT狀態表示客戶端已發送SYN報文。

  ESTABLISHED:這個容易理解了,表示連接已經建立了

相關知識: SYN攻擊

在三次握手過程中,Server發送SYN-ACK之后,收到Client的ACK之前的TCP連接稱為半連接(half-open connect),此時Server處于SYN_RCVD狀態,當收到ACK后,Server轉入ESTABLISHED狀態。SYN攻擊就是Client在短時間內偽造大量不存在的IP地址,并向Server不斷地發送SYN包,Server回復確認包,并等待Client的確認,由于源地址是不存在的,因此,Server需要不斷重發直至超時,這些偽造的SYN包將長時間占用未連接隊列,導致正常的SYN請求因為隊列滿而被丟棄,從而引起網絡堵塞甚至系統癱瘓。SYN攻擊時一種典型的DDOS攻擊,檢測SYN攻擊的方式非常簡單,即當Server上有大量半連接狀態且源IP地址是隨機的,則可以斷定遭到SYN攻擊了,使用如下命令可以讓之現行:
#netstat -nap | grep SYN_RECV

3、“四次揮手”斷開連接

所謂四次揮手(Four-Way Wavehand)即終止TCP連接,就是指斷開一個TCP連接時,需要客戶端和服務端總共發送4個包以確認連接的斷開。在socket編程中,這一過程由客戶端或服務端任一方執行close來觸發,整個流程如下圖所示:

由于TCP連接時全雙工的,因此,每個方向都必須要單獨進行關閉,這一原則是當一方完成數據發送任務后,發送一個FIN來終止這一方向的連接,收到一個FIN只是意味著這一方向上沒有數據流動了,即不會再收到數據了,但是在這個TCP連接上仍然能夠發送數據,直到這一方向也發送了FIN。首先進行關閉的一方將執行主動關閉,而另一方則執行被動關閉,上圖描述的即是如此。
(1)第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態。
(2)第二次揮手:Server收到FIN后,發送一個ACK給Client,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號),Server進入CLOSE_WAIT狀態。
(3)第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態。
(4)第四次揮手:Client收到FIN后,Client進入TIME_WAIT狀態,接著發送一個ACK給Server,確認序號為收到序號+1,Server進入CLOSED狀態,完成四次揮手

狀態詳解:

  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連接,但另外還告訴對方,我暫時還有點數據需要傳送給你,稍后再關閉連接。
  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可用狀態了。

關于TIME_WAIT 狀態更詳細的可以參考我的另一篇博文:

TIME_WAIT狀態解析

4、TCP端口:

TCP協議所涉及的端口是指用于面向連接或無連接的通信協議端口,是網絡通信進程的一種標識,其屬于一種抽象的軟件結構,屬于軟件端口范疇。在TCP協議中,端口操作類似于一般的I/O操作,進程獲取一個端口,相當于獲取本地唯一的I/O文件,可以用一般的讀寫式訪問。詳細解析請看我的另一篇博文:

常見的網絡端口

5、可靠傳輸

TCP可靠傳輸的工作原理
1.無差錯
1):無差錯: A發送分組M1,發送就暫停發送,等待B的確認,B收到M1就向A發送確認,A收到對M1的確認后再發送下一個分組。(若A收到連續的M1分組的確認信息,則證明M2缺失)
2):出現差錯:A只要超過一段時間仍然沒有收到確認,就認為剛才發送的分組丟失了,就重傳前面發過的分組,叫超時重傳。由重傳計時器實現。
而且:

(1)A每次發送分組必須暫時保留分組副本;

(2)分組和確認分組必須進行編號‘

(3)超時計時器的重傳時間應當比數據在分組的平均往返時間更多一些。

3):如果B收到重復的分組M1,不向上一層交付;而且,向A發送確認。

2.超時重傳
其原理是在發送某一個數據以后就開啟一個計時器,在一定時間內如果沒有得到發送的數據報的ACK報文,那么就重新發送數據,直到發送成功為止。

3.停止等待協議
優點是簡單,但是信道利用率太低了。解決方法是采用連續ARQ協議,發送方維持發送窗口,每次連續發送幾個分組,接收方采用累積確認,對按序到達的最后一個分組發送確認。

缺點是不能向發送方反映出接收方已經正確收到的所有分組信息,例如丟失中間的分組。

4.TCP可靠傳輸的實現

TCP 連接的每一端都必須設有兩個窗口——一個發送窗口和一個接收窗口。TCP 的可靠傳輸機制用字節的序號進行控制。TCP 所有的確認都是基于序號而不是基于報文段。
發送過的數據未收到確認之前必須保留,以便超時重傳時使用。發送窗口不動(沒收到確認)和前移(收到新的確認)
發送緩存用來暫時存放: 發送應用程序傳送給發送方 TCP 準備發送的數據;TCP 已發送出但尚未收到確認的數據。接收緩存用來暫時存放:按序到達的、但尚未被接收應用程序讀取的數據; 不按序到達的數據。
必須強調三點:
1) A 的發送窗口并不總是和 B 的接收窗口一樣大(因為有一定的時間滯后)。

2) TCP 標準沒有規定對不按序到達的數據應如何處理。通常是先臨時存放在接收窗口中,等到字節流中所缺少的字節收到后,再按序交付上層的應用進程。
3) TCP 要求接收方必須有累積確認的功能,這樣可以減小傳輸開銷

5.滑動窗口圖解

6、流量控制

流量控制方面主要有兩個要點需要掌握。一是TCP利用滑動窗口實現流量控制的機制;二是如何考慮流量控制中的傳輸效率。

  • 流量控制

    所謂流量控制,主要是接收方傳遞信息給發送方,使其不要發送數據太快,是一種端到端的控制。主要的方式就是返回的ACK中會包含自己的接收窗口的大小,并且利用大小來控制發送方的數據發送:

  • 這里面涉及到一種情況,如果B已經告訴A自己的緩沖區已滿,于是A停止發送數據;等待一段時間后,B的緩沖區出現了富余,于是給A發送報文告訴A我的rwnd大小為400,但是這個報文不幸丟失了,于是就出現A等待B的通知||B等待A發送數據的死鎖狀態。為了處理這種問題,TCP引入了持續計時器(Persistence timer),當A收到對方的零窗口通知時,就啟用該計時器,時間到則發送一個1字節的探測報文,對方會在此時回應自身的接收窗口大小,如果結果仍未0,則重設持續計時器,繼續等待。
  • 傳遞效率

    一個顯而易見的問題是:單個發送字節單個確認,和窗口有一個空余即通知發送方發送一個字節,無疑增加了網絡中的許多不必要的報文(請想想為了一個字節數據而添加的40字節頭部吧!),所以我們的原則是盡可能一次多發送幾個字節,或者窗口空余較多的時候通知發送方一次發送多個字節。對于前者我們廣泛使用Nagle算法,即:
    *1. 若發送應用進程要把發送的數據逐個字節地送到TCP的發送緩存,則發送方就把第一個數據字節先發送出去,把后面的字節先緩存起來;
    *2. 當發送方收到第一個字節的確認后(也得到了網絡情況和對方的接收窗口大小),再把緩沖區的剩余字節組成合適大小的報文發送出去;
    *3. 當到達的數據已達到發送窗口大小的一半或以達到報文段的最大長度時,就立即發送一個報文段;
    對于后者我們往往的做法是讓接收方等待一段時間,或者接收方獲得足夠的空間容納一個報文段或者等到接受緩存有一半空閑的時候,再通知發送方發送數據。

  • 7、擁塞控制

    網絡中的鏈路容量和交換結點中的緩存和處理機都有著工作的極限,當網絡的需求超過它們的工作極限時,就出現了擁塞。擁塞控制就是防止過多的數據注入到網絡中,這樣可以使網絡中的路由器或鏈路不致過載。常用的方法就是:
    1. 慢開始、擁塞控制
    2. 快重傳、快恢復

    一切的基礎還是慢開始,這種方法的思路是這樣的:
    1). 發送方維持一個叫做“擁塞窗口”的變量,該變量和接收端口共同決定了發送者的發送窗口;
    2). 當主機開始發送數據時,避免一下子將大量字節注入到網絡,造成或者增加擁塞,選擇發送一個1字節的試探報文;
    3). 當收到第一個字節的數據的確認后,就發送2個字節的報文;
    4). 若再次收到2個字節的確認,則發送4個字節,依次遞增2的指數級;
    5). 最后會達到一個提前預設的“慢開始門限”,比如24,即一次發送了24個分組,此時遵循下面的條件判定:
    *1. cwnd < ssthresh, 繼續使用慢開始算法;
    *2. cwnd > ssthresh,停止使用慢開始算法,改用擁塞避免算法;
    *3. cwnd = ssthresh,既可以使用慢開始算法,也可以使用擁塞避免算法;
    6). 所謂擁塞避免算法就是:每經過一個往返時間RTT就把發送方的擁塞窗口+1,即讓擁塞窗口緩慢地增大,按照線性規律增長;
    7). 當出現網絡擁塞,比如丟包時,將慢開始門限設為原先的一半,然后將cwnd設為1,執行慢開始算法(較低的起點,指數級增長);

    上述方法的目的是在擁塞發生時循序減少主機發送到網絡中的分組數,使得發生擁塞的路由器有足夠的時間把隊列中積壓的分組處理完畢。慢開始和擁塞控制算法常常作為一個整體使用,而快重傳和快恢復則是為了減少因為擁塞導致的數據包丟失帶來的重傳時間,從而避免傳遞無用的數據到網絡。快重傳的機制是:

    1). 接收方建立這樣的機制,如果一個包丟失,則對后續的包繼續發送針對該包的重傳請求;
    2). 一旦發送方接收到三個一樣的確認,就知道該包之后出現了錯誤,立刻重傳該包;
    3). 此時發送方開始執行“快恢復”算法:
    *1. 慢開始門限減半;
    *2. cwnd設為慢開始門限減半后的數值;
    *3. 執行擁塞避免算法(高起點,線性增長);

    二、UDP協議

    1、定義:

    用戶數據報協議是一種無連接的傳輸層協議,提供面向事務的不可靠信息傳送服務。UDP協議基本上是IP協議與上層協議的接口,適用于端口分別運行在同一臺設備上的多個應用程序。

    2、特點:

    1)無連接,發送數據之前不需要建立連接。開銷和發送之前的時間延遲較短。

    2)盡最大努力交付。(可以采取一定策略實現可靠傳輸)

    3)面向報文,UDP對應用程序交付的報文,添加UDP首部后直接交給IP層。不合并,不拆分。

    4)沒有擁塞控制,網絡擁塞不會使源主機發送率降低。

    5)UDP支持一對一,一對多,多對一的交互通信

    6)UDP首部開銷較小,8字節(TCP為20字節、IP為20字節)

    3、數據報格式

    用戶數據報UDP有兩個字段:<數據>字段和<首部>字段。
    首部字段很簡單,只有8個字節,由4個字段組成,每個字段的長度都是兩個字節。

    各字段的意義如下:
    1.源端口
    源端口號,在需要對方回信的時候選用,不需要的時候可用全0

    2.目的端口
    目的端口號,這在終點交付報文時必須要使用到。

    3.長度
    UDP用戶數據報的長度(首部字段和數據字段),其最小值是8,也即是只有首部。

    4.檢驗和
    在進行檢驗和計算時,會添加一個偽首部一起進行運算。偽首部(占用12個字節)為:4個字節的源IP地址、4個字節的目的IP地址、1個字節的0、一個字節的數字17、以及占用2個字節UDP長度。這個偽首部不是報文的真正首部,只是引入為了計算校驗和。相對于IP協議的只計算首部,UDP檢驗和會把首部和數據一起進行校驗。接收端進行的校驗和與UDP報文中的校驗和相與,如果無差錯應該全為1。如果有誤,則將報文丟棄或者發給應用層、并附上差錯警告。

    三、TCP協議與UDP協議的區別

    TCP(Transmission Control Protocol)可靠的、面向連接的協議(eg:打電話)、傳輸效率低全雙工通信(發送緩存&接收緩存)、面向字節流。使用TCP的應用:Web瀏覽器;電子郵件、文件傳輸程序。

    UDP(User Datagram Protocol)不可靠的、無連接的服務,傳輸效率高(發送前時延小),一對一、一對多、多對一、多對多、面向報文,盡最大努力服務,無擁塞控制。使用UDP的應用:域名系統 (DNS);視頻流;IP語音(VoIP)。

    常見的問題:

    問題1:什么是面向連接、面向無連接?

    面向連接舉例:兩個人之間通過電話進行通信。

    面向無連接舉例:郵政服務,用戶把信函放在郵件中期待郵政處理流程來傳遞郵政包裹。顯然,不可達代表不可靠。

    從程序實現的角度解析面向連接、面向無連接如下:TCP面向連接,UDP面向無連接(在默認的阻塞模式下)

    在TCP協議中,當客戶端退出程序或斷開連接時,TCP協議的recv函數會立即返回不再阻塞,因為服務端自己知道客戶端已經退出或斷開連接,證明它是面向連接的;而在UDP協議中,recvfrom這個接收函數將會始終保持阻塞,因為服務端自己不知道客戶端已經退出或斷開連接,證明它是面向無連接的)。

    從上圖也能清晰的看出,TCP通信需要服務器端偵聽listen、接收客戶端連接請求accept,等待客戶端connect建立連接后才能進行數據包的收發(recv/send)工作。

    而UDP則服務器和客戶端的概念不明顯,服務器端即接收端需要綁定端口,等待客戶端的數據的到來。后續便可以進行數據的收發(recvfrom/sendto)工作。

    問題2:什么是面向字節流、面向報文?

    面向字節流:雖然應用程序和TCP的交互是一次一個數據塊(大小不等),但TCP把應用程序看成是一連串的無結構的字節流。TCP有一個緩沖,當應用程序傳送的數據塊太長,TCP就可以把它劃分短一些再傳送。如果應用程序一次只發送一個字節,TCP也可以等待積累有足夠多的字節后再構成報文段發送出去。

    面向報文:面向報文的傳輸方式是應用層交給UDP多長的報文,UDP就照樣發送,即一次發送一個報文。因此,應用程序必須選擇合適大小的報文。若報文太長,則IP層需要分片,降低效率。若太短,會是IP太小。(謝希仁,第五版。UDP對應用層交下來的報文,既不合并,也不拆分,而是保留這些報文的邊界。這也就是說,應用層交給UDP多長的報文,UDP就照樣發送),即一次發送一個報文)。

    問題3:在默認的阻塞模式下,為什么說TCP無邊界,UDP有邊界?

    對于TCP協議,客戶端連續發送數據,只要服務端的這個函數的緩沖區足夠大,會一次性接收過來,即客戶端是分好幾次發過來,是有邊界的,而服務端卻一次性接收過來,所以證明是無邊界的;

    而對于UDP協議,客戶端連續發送數據,即使服務端的這個函數的緩沖區足夠大,也只會一次一次的接收,發送多少次接收多少次,即客戶端分幾次發送過來,服務端就必須按幾次接收,從而證明,這種UDP的通訊模式是有邊界的。

    問題4:UDP 如何發送大量的數據?如何處理分包?

    用 updclient 一次不能發送太大的數據量,不然就會報錯:一個在數據報套接字上發送的消息大于內部消息緩沖器或其他一些網絡限制,或該用戶用于接收數據報的緩沖器比數據報小。但不知道一次到底能發多少字節?如果把一個大的字節數組拆分成若干個字節數組發送,那么接收時如何判斷和處理呢?

    答:方法很簡單:

    1、在客戶端將你要發送的內容(文件什么的都可以)分塊,每塊內容進行編號,然后發送;

    2、服務端在接收到你的分塊數據以后,根據你的客戶端數據內容的編號重新組裝;

    3、一般我們在發送數據的時候,盡量采用比較小的數據塊的方式(我的都沒有超過1024的),數據塊太大的話容易出現發送和接收的數據時間長,匹配出問題。

    問題5.UDP發包的問題

    問:udp發送兩次數據,第一次 100字節,第二次200字節,接包方一次recvfrom( 1000 ),收到是 100,還是200,還是300?

    答:UDP是數據報文協議,是以數據包方式,所以每次可以接收100,200,在理想情況下,第一次是無論recvfrom多少都是接收到100。當然,可能由于網絡原因,第二個包先到的話,有可能是200了。對可能會由于網絡原因亂序,所以可能先收到200,所以自定義的udp協議包頭里都要加上一個序列號,標識發送與收包對應。

    問題6.TCP的發包問題

    問:同樣如果換成tcp,第一次發送 100字節,第二次發送200字節,recv( 1000 )會接收到多少?

    答:tcp是流協議,所以recv( 1000 ),會收到300 tcp自己處理好了重傳,保證數據包的完整性

    問題7.有分片的情況下如下處理

    問:如果MTU是1500,使用UDP發送 2000,那么recvfrom(2000)是收到1500,還是2000?

    答:還是接收2000,數據分片由ip層處理了,放到udp還是一個完整的包。接收到的包是由路由路徑上最少的MTU來分片,注意轉到UDP已經在是組裝好的(組裝出錯的包會經crc校驗出錯而丟棄),是一個完整的數據包。

    問題8.分片后的處理

    問:如果500那個片丟了怎么辦?udp又沒有重傳

    答:udp里有個crc檢驗,如果包不完整就會丟棄,也不會通知是否接收成功,所以UDP是不可靠的傳輸協議,而且TCP不存在這個問題,有自己的重傳機制。在內網來說,UDP基本不會有丟包,可靠性還是有保障。當然如果是要求有時序性和高可靠性,還是走TCP,不然就要自己提供重傳和亂序處理( UDP內網發包處理量可以達 7M~10M/s )

    問題9.不同連接到同一個端口的包處理

    問:TCP

    A -> C發100

    B -> C發200

    AB同時同一端口

    C recv(1000) ,會收到多少?

    答:A與C是一個tcp連接,B與C又是另一個tcp連接,所以不同socket,所以分開處理。每個socket有自己的接收緩沖和發送緩沖

    問題10.什么是TCP粘包

    在應用開發過程中,基于TCP網絡傳輸的應用程序有時會出現粘包現象(即發送方發送的若干包數據到接收方接收時粘成一包)。詳細解釋如下:由于TCP是流協議,對于一個socket的包,如發送 10AAAAABBBBB兩次,由于網絡原因第一次又分成兩次發送, 10AAAAAB和BBBB,如果接包的時候先讀取10(包長度)再讀入后續數據,當接收得快,發送的慢時,就會出現先接收了 10AAAAAB,會解釋錯誤 ,再接到BBBB10AAAAABBBBB,也解釋錯誤的情況。這就是TCP的粘包。

    在網絡傳輸應用中,通常需要在網絡協議之上再自定義一個協議封裝一下,簡單做法就是在要發送的數據前面再加一個自定義的包頭,包頭中可以包含數據長度和其它一些信息,接收的時候先收包頭,再根據包頭中描述的數據長度來接收后面的數據。詳細做法是:先接收包頭,在包頭里指定包體長度來接收。設置包頭包尾的檢查位(如群空間0x2開頭,0x3結束來檢查一個包是否完整)。對于TCP來說:1)不存在丟包,錯包,所以不會出現數據出錯 2)如果包頭檢測錯誤,即為非法或者請求,直接重置即可

    為了避免粘包現象,可采取以下幾種措施:

    一是對于發送方引起的粘包現象,用戶可通過編程設置來避免,TCP提供了強制數據立即傳送的操作指令push,TCP軟件收到該操作指令后,就立即將本段數據發送出去,而不必等待發送緩沖區滿;

    二是對于接收方引起的粘包,則可通過優化程序設計、精簡接收進程工作量、提高接收進程優先級等措施,使其及時接收數據,從而盡量避免出現粘包現象;

    三是由接收方控制,將一包數據按結構字段,人為控制分多次接收,然后合并,通過這種手段來避免粘包。

    總結

    以上是生活随笔為你收集整理的传输层两大协议:TCP与UDP详解(两者的联系与区别)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。