2015-03-30 4 views
3

Я пытаюсь изменить размер буфера отправки сокета по умолчанию на небольшой размер, , чтобы узнать, как влияет пропускная способность UDP для небольших дейтаграмм UDP. Для этого я использую функцию setsockopt с опцией SO_SNDBUF и . Я пытаюсь установить размер буфера 64 байта. Я также использую getsockopt, чтобы увидеть результат функции setsockopt.Есть ли способ уменьшить минимальный нижний предел размера буфера отправки сокета?

Вот код, я использую:

int sock_fd; 
struct sockaddr_in server_addr; 
static int target_port = PORT; 
int curr_snd_buff = 0; 
int sk_snd_buff = 64; 
socklen_t optlen; 

if((sock_fd=socket(AF_INET,SOCK_DGRAM,0)) == -1) 
fatal("in socket (client_udp)"); 

memset(&server_addr, 0, sizeof(struct sockaddr_in)); 

server_addr.sin_family = AF_INET;                       
server_addr.sin_addr.s_addr=inet_addr(args->a_ip); 
server_addr.sin_port=htons(target_port); 

if (sk_snd_buff > 0)                          >{                          
    optlen = sizeof(sk_snd_buff); 
    // get the default socketh send buffer size 
if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &curr_snd_buff, &optlen) == -1) { 
    fatal("getting the socket send buffer"); 
    } 
    printf("* default socket send buffer: %d\n", curr_snd_buff); 
    printf("* attempting to change it to: %d\n", sk_snd_buff); 
    if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &sk_snd_buff, optlen) == -1) { 
    fatal("changing the socket send buffer"); 
    } 
    if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &curr_snd_buff, &optlen) == -1) { 
    fatal("getting the socket send buffer"); 
    } 
    printf("* new socket send buffer: %d\n", curr_snd_buff); 
} 

Но то, что я вижу в том, что существует нижний предел размера буфера, установленного в 4608 байт каждый раз, когда я пытаюсь установить небольшое значение. Вот выход из приведенного выше кода:

  • по умолчанию буфера сокета: 212992
  • пытается изменить его на: 2304
  • новый сокет буфер посылки: 4608

Пробуя различные размеры , Я обнаружил, что это происходит для размеров < = 2304. Для больших размеров, например 2305, я получаю больший размер:

  • по умолчанию сокет отправить буфер: 212992
  • пытается изменить его на: 2305
  • новый сокет отправить буфер: 4610

и для некоторых больших размеров , например 3000, удвоенная размера, что у меня есть запрошенную:

  • по умолчанию буфера сокета: 212992
  • пытается изменить его на: 3000
  • новый сокет отправить буфер: 6000

Просматривая сеть, я обнаружил, что Linux удваивает значение в пределах ядра при его установке и возвращает удвоенное значение, когда вы его запрашиваете: Understanding set/getsockopt SO_SNDBUF

Есть ли способ уменьшить минимальную нижнюю границу размера буфера отправки сокета? Например, чтобы установить его на 64 байта?

+1

'printf (" * попытка изменить его на:% d \ n ", sk_snd_buff);' <- Whoa! Почему эта печать 2304, если sk_snd_buff была инициализирована до 64 и не изменилась после этого? У вас где-то есть повреждение памяти? Вы должны сначала отладить это. – immibis

+0

Минимальный размер фиксируется на 2048 (удваивается). Максимум может быть установлен в '/ proc/sys/net/core/wmem_max'. Я предполагаю, что единственный способ изменить это - взломать ядро. –

+0

Чтобы добавить комментарий, написанный @immibis, что говорит valgrind? – Sebivor

ответ

3

Минимальный размер буфера является функцией ядра. В документах Linux для опции SO_SNDBUF есть что сказать:

Устанавливает или получает максимальный буфер отправки сокета в байтах. Ядро удваивает это значение (чтобы освободить место для служебных расходов), когда оно установлено с помощью setsockopt (2), и это удвоенное значение возвращается getsockopt (2). Значение по умолчанию устанавливается файлом/proc/sys/net/core/wmem_default, а максимальное допустимое значение устанавливается файлом/proc/sys/net/core/wmem_max. Минимальное (удвоенное) значение для этой опции - 2048.

(гнездо (7) страница руководства)

Детали, скорее всего, меняться на разных системах, но

  1. Это объясняет удвоение вы видите - мощность буфера для исходящих байт размер вы но ядро ​​резервирует и сообщает, что в два раза больше пространства.
  2. В Linux, по крайней мере, вы не сможете установить как небольшой буфер, как вы говорите, вы хотите. Я бы предположил, что другие системы будут иметь ограничения того же порядка величины.