2012-11-24 206 views
1

我正在編寫一個小程序來測試網絡吞吐量作爲練習的一部分,並且需要將發送和接收緩衝區增加到256 KB(以嘗試提高TCP性能)。我正在使用setsockopt()和SO_SNDBUF/SO_RCVBUF選項執行此操作,並且還增加了'net.core.rmem_max'和'net.core.wmem_max'值。TCP網絡吞吐量測量

getsockopt()確認緩衝區大小的增加(雙倍的256KB值),所以我知道這很好。然而,當我從一臺主機向另一臺主機發送256KB數據時,接收器總是以幾種不同大小的讀取方式接收數據(大約20到40次讀取,其範圍從1448到18824),直到接收到所有數據。我很困惑,在這一點上主要是與這些問題,

  1. 隨着增加的緩衝區大小不應該它在一次讀取?
  2. 此外,爲什麼每次讀取的字節數量差異如此之大(不應該它們更不穩定)?
  3. 是否有某種方法可以確保在一次讀取中接收到256KB?

下面是表示該讀部分接收端片段,

while(1) { 
    memset(&client_addr, 0, sizeof(client_addr)); 
    if ((connfd = accept(listenfd, (struct sockaddr*)&client_addr, &socklen)) <= 0) { 
     perror("accept()"); 
     exit(EXIT_FAILURE); 
    } 

    while ((n = recv(connfd, &buff[0], BUFF_SIZE, 0/*MSG_WAITALL*/)) > 0) { 
     totalBytes += n; 
     ++pktCount; 
     printf("Received(%d): %d bytes\n", pktCount, n); 
    } 

    if (n == 0) { 
     printf("Connection closed (Total: %lu bytes received)\n", totalBytes); 
    } 

    close(connfd); 
    connfd = -1; 
    totalBytes = 0; 
    pktCount = 0; 
    } 

任何幫助將是巨大的。

TIA

+1

[MTU](https://en.wikipedia.org/wiki/Maximum_transmission_unit#Table_of_MTUs_of_common_media)。 ACK數據包也需要發回。 – 2012-11-24 17:24:58

+0

TCP是面向流的協議,不是數據報。每次讀取的數據量取決於MSS(取決於網絡MTU)和TCP窗口大小。這就是爲什麼在單個TCP連接上運行的面向消息的協議通常使用額外的數據成幀,例如每條消息都以其長度爲前綴,以便讀者知道何時停止從套接字讀取與當前消息相關的數據。 –

回答

2

隨着增加緩衝區的大小不應該是收到一個讀?

編號TCP/IP是一種流媒體協議,通過較小的數據包將數據分段。緩衝區大小主要影響底層網絡層實現可以使用多少內存(並且Linux通常會將您設置的數量增加一倍),但不能保證接收端將以與發送端發送數據大小完全相同的數據塊接收數據(之後總之,當你調用send()/write(),這並不意味着數據包被髮送,實際上,還有,你是最有可能分裂你的數據包反正由於MTU

而且爲什麼在每個字節量閱讀差異如此之大(不應該他們更不穩定)?

您可能想調試爲什麼發生這種情況。紅色的因素 - 使用中的網卡,它的設置,它的驅動程序,TCP/IP,TCP,以太網網絡層設置,發件人和收件人之間的內容。一個開關)等等。但是,當你的操作系統和應用程序正在處理上一個塊時,會有更多的數據進入。鑑於將數據從NIC傳遞到用戶空間應用程序相對非常昂貴,因此數據被緩衝並獲得不同大小並不奇怪。

是否有某種方法可確保在一次讀取中接收到256KB?

可能有。有人可能會使用阻塞read(),並要求OS只在收到至少256KB或發生錯誤時才喚醒進程。

+0

「有人可能會使用一個阻塞的'read()',並要求OS只在收到至少256KB或發生錯誤時才喚醒進程。」我非常有興趣瞭解如何做到這一點。 –

+2

MSG_WAITALL標誌這麼做(至少在我的Linux機器上)。 –

2

您將有大約180個數據包要發送,而這些數據不在大量數據附近。Nagle將導致任意數量的數據包被任一操作系統緩衝,同時發送和接收。

任何緩衝數據包將通過recv()呈現時的觸發器已達到實施。它可能會在一段時間後或者在達到一定數量的內部緩衝區大小之後呈現所有數據包。在某些操作系統中,您可以使用SO_RCVLOWAT套接字選項更改這些級別。

+0

我想對此表示讚賞,但它需要更多信息。雖然它涵蓋了一些優點,但它並不真正回答OP這樣的問題,就像其他答案一樣。 –

+0

@Joshua它並不直接回答OP的問題,因爲不僅四年前的答案,我們都在此期間學到了很多,但主要是因爲正確答案是「最佳緩衝區大小因網絡和平臺而異,以此爲基準「_」。解釋可能導致這些差異的因素不適用於單個答案。 – CodeCaster

+0

確切地說,但是......有人問這個問題的唯一方法是要知道「爲什麼」發生這種情況,如果它被正確解釋(即使是在高層次),以便這些過程的工作方式可以被理解。你不會告訴某人「你不能炸雞,因爲它沒有準備好」,然後繼續不解釋需要什麼樣的準備。這個過程雖然可能在較低層次上覆雜化,但在較高層次上傳達並不困難。請看@ user405725的回答,看看他們如何解決OP對流程的誤解,以更好地解釋「發生了什麼」。 –