2017-10-05 86 views
0

爲什麼在設置套接字發送/接收緩衝區大小高於sysctl max時沒有錯誤(如下面所示)? 「預期的行爲」沒有錯誤?爲什麼在設置套接字發送/接收緩衝區大小高於sysctl max時沒有錯誤?


sysctl值插座rmem_maxwmem_max都設置爲212992:

net.core.rmem_default = 212992 
net.core.rmem_max = 212992 
net.core.wmem_default = 212992 
net.core.wmem_max = 212992 
net.ipv4.tcp_rmem = 4096 87380 6291456 
net.ipv4.tcp_wmem = 4096 16384 4194304 
net.ipv4.udp_rmem_min = 4096 
net.ipv4.udp_wmem_min = 4096 
vm.lowmem_reserve_ratio = 256 256 32 

當我創建一個套接字,並嘗試套接字緩衝區的大小爲64 * 1024 * 1024(一值比rmem_maxwmem_max更高版本),同時發送/接收:

#include <cstdlib> 
#include <cstring> 
#include <iostream> 
#include <boost/asio.hpp> 
#include <boost/format.hpp> 

using boost::asio::ip::udp; 
using boost::format; 
using namespace std; 

int main() 
{ 
    try 
    { 
     boost::asio::io_service io_service; 
     udp::socket socket(io_service, udp::endpoint(udp::v4(), 0)); 
     udp::resolver resolver(io_service); 
     udp::resolver::query query(udp::v4(), "localhost", "7770"); 
     udp::resolver::iterator iterator = resolver.resolve(query); 

     boost::system::error_code error_code; 
     socket.set_option(boost::asio::socket_base::send_buffer_size(64*1024*1024), error_code); 
     cout << error_code << endl; 
     boost::asio::socket_base::send_buffer_size send_buffer_size; 
     socket.get_option(send_buffer_size); 
     cout << format("send_buffer_size=%s") % send_buffer_size.value() << endl; 

     socket.set_option(boost::asio::socket_base::receive_buffer_size(64*1024*1024), error_code); 
     cout << error_code << endl; 
     boost::asio::socket_base::receive_buffer_size receive_buffer_size; 
     socket.get_option(receive_buffer_size); 
     cout << format("receive_buffer_size=%s") % receive_buffer_size.value() << endl; 
    } 
    catch (std::exception& e) 
    { 
     std::cerr << "Exception: " << e.what() << "\n"; 
    } 

    return 0; 
} 

我期待看到一個錯誤,而是我沒有得到任何錯誤:

system:0 
send_buffer_size=212992 
system:0 
receive_buffer_size=212992 

如果設置緩衝區大小不報告的錯誤是「預期的行爲」爲setsockopt(),我想適當的代碼是請在致電setsockopt()後檢查數值,並提出我自己的錯誤或警告。

+1

這些選項的行爲不是標準化的。您必須實施針對您支持的每個平臺的行爲。令人感到奇怪的是,有些平臺幾乎不會讀回您設置的相同尺寸,因爲他們測量的尺寸與他們設置的方式不同。 –

+0

我一直都知道,雖然現在不能找到它的寫入位置,但系統可以調整您指定的大小,並且需要調用'getsockopt()'來查明實際的分配情況。 – EJP

回答

1

爲什麼在設置套接字發送/接收緩衝區大小高於sysctl max時沒有錯誤(正如我在下面演示的)? 「預期的行爲」沒有錯誤?

POSIX對此沒有明確說明。如果無法爲有效選項設置指定值,但它不包含許可setsockopt()失敗(返回-1和設置errno),但是該場景不在其中需要實現失敗的那些場景中。尤其是,如果您參考the specifications,則在setsockopt()的故障條件列表中找不到您的方案。最接近的是「指定的選項在指定的套接字級別無效或套接字已關閉」,但在指定的套接字級別上無效只能應用於選項本身,而不適用於爲其指定的值。

此外,its description of the receive buffer and send buffer options將其特別表徵爲請求以設置指定的緩衝區大小。例如:

,對於 緩衝空間分配的SO_RCVBUF選項請求收到此套接字上操作設置的值,以字節爲單位的 期權價值。 [...]

大多數其他選項的描述更確定,通常使用動詞「sets」而不是「requests」。也許我正在讀的太多,但對我來說,如果這是一個請求,那麼實現並不一定會兌現。 setsockopt()的成功則是它是否提供請求的函數,而不是請求是否得到遵守。

您的評論:

如果設置緩衝區大小不報告的錯誤是「預期 行爲」爲setsockopt(),我想適當的代碼是 調用setsockopt()後經常檢查值和提出我自己的 錯誤或警告。

如果您要舉報的setsockopt()未能設置你指定的緩衝區大小,那麼你的確應該能夠讀懂他們通過getsockopt()回查。 POSIX指定這些特定選項的值以字節表示緩衝區大小;因此,在一致性實施中,提供給setsockopt的值與通過getsockopt獲得的值相當。

但是,您可能會感到驚訝。我可以想象出幾個合適的變化,這兩個變化如何是兩個人無法準確匹配的例行程序。

相關問題