问题
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"?
My sysctl
values for socket rmem_max
and wmem_max
are both set to 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
When I create a socket and try to set the socket buffer size to 64*1024*1024 (a value greater than the rmem_max
and wmem_max
) for both send/receive:
#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;
}
I am expecting to see an error, but instead I don't get any errors:
system:0
send_buffer_size=212992
system:0
receive_buffer_size=212992
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.
回答1:
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 is not explicit about that. It does implicitly permit setsockopt()
to fail (returning -1 and setting errno
) in the event that the specified value cannot be set for a valid option, but that scenario is not among those in which it requires implementations to fail. In particular, if you refer to the specifications, you will not find your scenario on the list of failure conditions for setsockopt()
. The closest appears to be "The specified option is invalid at the specified socket level or the socket has been shut down," but being invalid at the specified socket level can only apply to the option itself, not the value specified for it.
Furthermore, its description of the receive buffer and send buffer options characterizes them in particular as requests to set the specified buffer sizes. For example:
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. [...]
Most other options are described more deterministically, often with use of the verb "sets" instead of "requests". Perhaps I'm reading too much into it, but to me, if it's a request then the implementation is not bound to honor it. Success of setsockopt()
is then a function of whether it delivers the request, not of whether the request was honored.
You remark:
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 callingsetsockopt()
and raise my own error or warning.
If you wish to report failure of setsockopt()
to set the exact buffer sizes you specify, then you should indeed be able to read them back via getsockopt()
to check. POSIX specifies that the values of these particular options express the buffer sizes in bytes; therefore, on a conforming implementation, the values provided to setsockopt
are comparable to those obtained via getsockopt
.
You might nevertheless be surprised, however. I can imagine several conforming variations on how it would be routine for the two to fail to match exactly.
来源:https://stackoverflow.com/questions/46591712/why-no-error-when-setting-socket-send-receive-buffer-size-higher-than-sysctl-max