Эффект SO_SNDBUF - PullRequest
       12

Эффект SO_SNDBUF

8 голосов
/ 13 ноября 2011

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

    /* Now lets try to set the send buffer size to 5000 bytes */
    size = 5000;
    err = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,  &size, sizeof(int));
    if (err != 0) {
        printf("Unable to set send buffer size, continuing with default size\n");
    }

Если мы проверяем значение буфера отправки, оно действительно правильно установлено на 5000 * 2 = 10000.Однако, если мы пытаемся отправить больше, чем размер буфера отправки, он отправляет все это.Например:

    n = send(sockfd, buf, 30000, 0);

    /* Lets check how much us actually sent */
    printf("No. of bytes sent is %d\n", n);

Это печатает 30000.

Как именно это работает?Разве тот факт, что размер буфера отправки был ограничен 10000, не имел никакого эффекта?Если это так, что именно произошло?Какая-то фрагментация?

ОБНОВЛЕНИЕ: Что произойдет, если сокет находится в неблокирующем режиме?Я попробовал следующее:

  1. Изменение размера буфера до 10000 (5000 * 2) приводит к отправке 16384 байта
  2. Изменение размера буфера до 20000 (10000 * 2) приводит к 30000 байтовбыть отправленным

Еще раз, почему?

Ответы [ 2 ]

12 голосов
/ 14 ноября 2011

Эффект установки опции SO_SNDBUF различен для TCP и UDP.

  • Для UDP это устанавливает ограничение на размер дейтаграммы , т. Е. Все большее будет отброшено.
  • Для TCP это просто устанавливает размер буфера в ядре для данного сокета (с некоторым округлением до границы страницы и с верхним пределом).

Поскольку похоже, что вы говорите о TCP, наблюдаемый эффект объясняется тем, что сокет находится в режиме блокировки , поэтому send(2) блокируется до тех пор, пока ядро ​​не сможет принять все ваши данные, и / или сетевой стек асинхронно выводит данные из очереди и помещает их в сетевую карту, освобождая место в буфере.

Кроме того, TCP является потоковым протоколом , он не сохраняет структуру "сообщения". Один send(2) может соответствовать нескольким recv(2) с другой стороны, и наоборот. Относитесь к нему как к потоку байтов.

4 голосов
/ 14 ноября 2011

SO_SNDBUF настраивает буфер, который реализация сокета использует внутренне.Если ваш сокет неблокирующий, вы можете отправлять только до настроенного размера, если ваш сокет блокируется, для вашего вызова нет ограничений.

...