c++ - 为什么设置套接字发送/接收缓冲区大小大于 sysctl max 时没有错误?

标签 c++ c sockets sysctl setsockopt

为什么在设置套接字发送/接收缓冲区大小大于 sysctl max 时没有错误(正如我在下面演示的那样)? “预期行为”没有错误吗?


我的套接字 rmem_maxwmem_maxsysctl 值都设置为 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( ) 并提出我自己的错误或警告。

最佳答案

Why no error when setting socket send/receive buffer size higher than sysctl max (as I have demonstrated below)? is no error the "expected behavior"?

POSIX 对此没有明确说明。如果无法为 a 设置指定值,它会隐式地允许 setsockopt() 失败(返回 -1 并设置 errno)有效的选项,但该场景不属于要求实现失败的场景。特别是,如果您引用 the specifications ,您不会在 setsockopt() 的失败条件列表中找到您的方案。最接近的似乎是“指定的选项在指定的套接字级别无效或套接字已关闭”,但是在指定的套接字级别无效只能应用于选项本身,而不适用于为其指定的值。

此外,its description of the receive buffer and send buffer options将它们特别描述为请求以设置指定的缓冲区大小。例如:

The SO_RCVBUF option requests that the buffer space allocated for receive operations on this socket be set to the value, in bytes, of the option value. [...]

大多数其他选项的描述更具确定性,通常使用动词“sets”而不是“requests”。也许我对它读得太多了,但对我来说,如果这是一个请求,那么实现不一定会遵守它。 setsockopt() 的成功是它是否传递请求的函数,而不是请求是否被兑现的函数。

你的评论:

If setting the buffer size does not report an error is the "expected behavior" for the setsockopt(), I guess the appropriate code is to always check the value after calling setsockopt() and raise my own error or warning.

如果您希望报告 setsockopt() 设置您指定的确切缓冲区大小失败,那么您确实应该能够通过 getsockopt() 读回它们去检查。 POSIX 指定这些特定选项的值表示缓冲区大小以字节为单位;因此,在一致的实现中,提供给 setsockopt 的值与通过 getsockopt 获得的值相当。

然而,您可能仍然会感到惊讶。我可以想象出几个一致的变体,说明两者无法完全匹配是很常见的。

关于c++ - 为什么设置套接字发送/接收缓冲区大小大于 sysctl max 时没有错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46591712/

相关文章:

c++ - getopt 参数取决于另一个

c++ - 我可以在已经由 main 创建的 pthread 中创建一个 pthread 吗?

sockets - 黑莓套接字连接-应用程序卡在acceptAndOpen()上

使用 g++ 4.6 和 boost::unordered_map 的 C++11 相关编译错误

c++ - 如何比较 strstr(LPCWSTR, CHAR*);

c++ - string::find() c++ 使用的字符串搜索算法

c++ - boost C++ : how to return file from folder via tcp?

c++ - 如何保护 MSI 不被修改

c - 错误: Conflicting types in structs pointers

java - Netty 4.0 ByteBuf keep() 使用