2016-03-01 81 views
1

我有一個關於套接字編程的問題。當我使用套接字發送數據時,我們可以使用sendto()等API使用TCP或UDP進行發送。 對於sendto(),我們給出一個數組指針和我們想要發送的字節數。在這種情況下,如果我給出了一個大的字節數(例如:20000字節),根據我的理解,網絡的MTU不會那麼大,所以socket實際上發送多個數據包而不是一個大數據包。由於這些20000字節被分成多個UDP/TCP數據包,但是這些20000字節在開始時會被看作是一個數據包嗎?這個過程是UDP/TCP碎片嗎?套接字編程,如果我寫入多個TCP/UDP數據包可以承載數據會發生什麼?

我的另一個問題是,如果我把數據大小比MTU小sendto(),那麼我可以保證調用sendto()一次,套接字只發送一個TCP/UDP數據包?

在此先感謝。

+0

UDP不會按照您描述的方式對數據進行分段。 UDP是一種面向消息的傳輸。您在UDP套接字上發送的內容將總是作爲單個數據包發送,或者根本不發送數據包。另一方面,TCP是一種面向數據流的傳輸方式,可以根據需要快速分解數據以適應網絡緩衝區。 'send()'/'sendto()'的返回值會告訴你到底有多少字節被傳輸,你必須注意它。 –

回答

2

這20000字節在開始時會被看作是一個數據包嗎?這個過程是UDP/TCP碎片嗎?

  1. 如果你的socket發送緩衝區足夠大的空間容納UDP將會把它作爲一個數據報。否則,你會得到EMSGSIZE。它可能隨後在IP層被分割,並且如果一個片斷丟失,那麼整個數據報也會丟失,但是如果所有片段都到達,那麼整個數據報將被原封不動地接收。

  2. TCP將發送它所有,分割和碎片它,但它認爲合適。除非有足夠長的網絡中斷,否則它將全部到達,完好無損。

我的另一個問題是,如果我把數據大小小於MTU到的sendto(),那麼我可以保證通話的sendto()一次,插座只發送一個TCP/UDP數據包?

  1. UDP:是的。
  2. TCP:no。
+0

TCP:no這是因爲數據大小必須小於MSS而不是MTU? – buddha

+0

@buddha沒有,因爲我上面說的:TCP可以segmentize它喜歡的任何方式。 – EJP

+0

好吧,我對「TCP可以以任何方式進行分段」的理解是,影響TCP分段的因素很多,例如網絡擁塞狀況,而不僅僅是MSS。 – buddha

相關問題