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

时间:2017-10-05 17:37:48

标签: c++ c sockets sysctl setsockopt

为什么设置套接字发送/接收缓冲区大小高于sysctl max时没有错误(如下所示)? "期望的行为"?

是没有错误的

套接字sysctlrmem_max的{​​{1}}值均设置为212992:

wmem_max

当我创建套接字并尝试将套接字缓冲区大小设置为64 * 1024 * 1024(大于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 rmem_max的值)时,发送/接收:

wmem_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;
}

如果设置缓冲区大小没有报告错误,那么&#34;预期的行为&#34;对于system:0 send_buffer_size=212992 system:0 receive_buffer_size=212992 ,我想相应的代码是在调用setsockopt()后始终检查该值并引发我自己的错误或警告。

1 个答案:

答案 0 :(得分:1)

  

为什么设置套接字发送/接收缓冲区大小高于sysctl max时没有错误(如下所示)? &#34;期望的行为&#34;?

是没有错误的

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

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

  

SO_RCVBUF选项请求分配的缓冲区空间   接收此套接字上的操作设置为的值,以字节为单位   期权价值。 [...]

大多数其他选项都经过更确定的描述,通常使用动词&#34; sets&#34;而不是&#34;请求&#34;。也许我已经读了太多内容,但对我来说,如果它是一个请求,那么实现并不一定要尊重它。 setsockopt()的成功是它是否提供请求的函数,而不是请求是否得到尊重。

你说:

  

如果设置缓冲区大小未报告错误,则为#34;预期   行为&#34;对于setsockopt(),我猜相应的代码是   在调用setsockopt()后总是检查该值并自行调整   错误或警告。

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

然而,你可能会感到惊讶。我可以想象几个一致的变化,两者如何不能完全匹配。