Может ли функция recv() получить больше байтов, чем ее внутренний буфер?

Я новичок в сокетах в Linux и пытаюсь понять, как recv() работает. Пробовал сценарий, где я не мог найти объяснение ясно. Я надеюсь, что кто-то там может просветить меня. Вот сценарий:

Использование TCP-сокетов для отправки данных размером 5 МБ между двумя процессами (Отправитель и Получатель). Я выполняю этот процесс на плате i.MX6 Sabrelite, которая работает под управлением Linux.

sender.cpp:

char buffer[5MB];
send(sendSocket, (void*) buffer, 5 MiB, 0);

receiver.cpp:

char buffer[5 MiB];
int count = 0;
do {
    rbytes = recv(receiveSocket, (void*) buffer, 5MB, 0);
    printf("Recv'd %d. %d\n",count,rbytes);
    count++;
} while (rbytes!=0);

Я использовал getsockopt() вызов функции перед получением для получения внутреннего буфера SO_RCVBUF размер. Это было около 86 КиБ.

Я хотел посмотреть, сколько recv() вызовов потребовалось, чтобы получить 5 МБ и сколько байт для каждого recv() вызов.

После получения 5 МиБ я проверяю вывод. Это почти занимает 48 recv() звонки, чтобы получить 5 МБ данных. Для первых 40 вызовов он получил менее 86 КиБ, что имеет смысл, поскольку количество полученных байтов меньше внутреннего буфера. Если я получил удвоение 86 КиБ, то я столкнулся с некоторым объяснением, что ядро ​​обычно выделяет вдвое больше, чем показано в SO_RCVBUF,

Но я получаю больше байтов, чем дубль 86 КиБ.

Могу ли я доверять SO_RCVBUF размер с помощью getsockopt()?

Динамически ли он меняет свои значения?

Просто попробовал еще одну итерацию по тому же сценарию. Номер recv() Звонок меняется. Но байты, которые я получаю, иногда более чем выделены.

1 ответ

Согласно этому потоку, ядро ​​выделяет в два раза больше буферного пространства, чем вы запрашиваете с помощью SO_RCVBUF.

Другие вопросы по тегам