Почему нет ошибки при установке размера буфера отправки / получения сокета, превышающего sysctl max?

Почему нет ошибки при установке размера буфера отправки / получения сокета выше, чем sysctl max (как я продемонстрировал ниже)? нет ошибки «ожидаемое поведение»?


мой sysctl значения для сокета rmem_max а также wmem_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_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;
}

Я ожидаю увидеть ошибку, но вместо этого я не получаю никаких ошибок:

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

Если установка размера буфера не сообщает об ошибке, это «ожидаемое поведение» для setsockopt()Я думаю, подходящий код всегда проверять значение после вызова setsockopt() и поднять мою собственную ошибку или предупреждение.

0

Решение

Почему нет ошибки при установке размера буфера отправки / получения сокета выше, чем sysctl max (как я продемонстрировал ниже)? нет ошибки «ожидаемое поведение»?

POSIX не говорит об этом явно. Это делает неявно разрешать setsockopt() потерпеть неудачу (возврат -1 и установка errno) в случае, если указанное значение не может быть установлено для действительной опции, но этот сценарий не входит в число тех, в которых оно требует реализации потерпеть неудачу. В частности, если вы ссылаетесь на технические характеристики, Вы не найдете свой сценарий в списке условий отказа для setsockopt(), Наиболее близким является «Указанная опция недопустима на указанном уровне сокета или сокет был выключен», но недействительна на указанном уровне сокета может применяться только к самой опции, а не к значению, указанному для нее.

Более того, его описание параметров буфера приема и буфера отправки характеризует их, в частности, как Запросы установить указанные размеры буфера. Например:

Опция SO_RCVBUF запрашивает, чтобы буферное пространство выделялось для
для операций приема на этом сокете должно быть установлено значение в байтах
значение опции. […]

Большинство других вариантов описаны более детерминистически, часто с использованием глагола «наборы» вместо «запросы». Возможно, я читаю слишком много, но для меня, если это запрос, то реализация не обязана его выполнять. Успех setsockopt() в этом случае зависит от того, доставляет ли он запрос, а не от того, был ли выполнен запрос.

Вы замечаете:

Если настройка размера буфера не сообщает об ошибке, то «ожидается»
поведение «для setsockopt()Я думаю, что соответствующий код
всегда проверяйте значение после звонка setsockopt() и поднять мой собственный
ошибка или предупреждение.

Если вы хотите сообщить о неудаче setsockopt() чтобы установить точный размер буфера, который вы укажете, тогда вы действительно сможете прочитать их обратно через getsockopt() Проверять. POSIX указывает, что значения этих конкретных параметров выражают размеры буфера в байтах; поэтому при соответствующей реализации значения, предоставленные setsockopt сопоставимы с полученными через getsockopt,

Тем не менее, вы можете быть удивлены. Я могу представить несколько соответствующих вариантов того, как было бы обычным для двух не соответствовать точно.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]