Может ли функция 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.