Пакет UDP-пакетов - INErrors Vs.RcvbufErrors

Я написал простую программу UDP Server, чтобы больше узнать о возможных узких местах сети.

Сервер UDP: создает сокет UDP, привязывает его к указанному порту и addr и добавляет дескриптор файла сокета в список интересов epoll. Тогда его epoll ждет входящего пакета. При приеме входящего пакета (EPOLLIN) он считывает пакет и просто печатает полученную длину пакета. Довольно просто, правильно:)

Клиент UDP: я использовал hping, как показано ниже:

hping3 192.168.1.2 --udp -p 9996 --flood -d 100

Когда я отправляю пакеты udp со 100 пакетами в секунду, я не нахожу потери UDP-пакета. Но когда я заливаю пакеты udp (как показано в приведенной выше команде), я вижу значительную потерю пакетов.

Test1: Когда из UDP-клиента заливается 26356 пакетов, моя примерная программа получает ТОЛЬКО 12127 пакетов, а остальные 14230 пакетов отбрасываются ядром, как показано в /proc/net/snmp.

cat/proc/net/snmp | grep Udp:
Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
Udp: 12372 0 14230 218 14230 0

Процент потери пакетов Test1 составляет ~ 53%.

Я подтвердил, что на аппаратном уровне не так много потерь, используя команду ethtool -S eспасибо как на стороне клиента, так и на стороне сервера, тогда как на уровне апплета я вижу потерю 53%, как было сказано выше.

Следовательно, чтобы уменьшить потерю пакетов, я пробовал:
- Увеличен приоритет моей выборки с помощью .
- Увеличенный размер буфера приема (как на уровне системы, так и на уровне процесса)

Повысьте приоритет до -20:

renice -20 2022
2022 (идентификатор процесса) старый приоритет 0, новый приоритет -20

Увеличьте размер буфера приема до 16 МБ:

На уровне процесса:
int sockbufsize = 16777216;
setockopt (sockfd, SOL_SOCKET, SO_RCVBUF, (char *) & sockbufsize, (int) sizeof (sockbufsize))
На уровне ядра:
cat/proc/sys/net/core/rmem_default
16777216
cat/proc/sys/net/core/rmem_max
16777216

После этих изменений выполняется Test2.

Test2: Когда из UDP-клиента заливается 1985076 пакетов, моя примерная программа получает пакеты 1848791, а оставшиеся пакеты 136286 получает ядро, как показано в /proc/net/snmp.

cat/proc/net/snmp | grep Udp:
Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
Udp: 1849064 0 136286 236 0 0

Для Test2 процент потери пакетов составляет 6%.

Потеря пакетов значительно снижается. Но у меня есть следующие вопросы:

  • Можно ли уменьшить потери пакетов?!? Я знаю, что я жадный здесь:) Но я просто пытаюсь выяснить, возможно ли уменьшить потери пакетов.
  • В отличие от Test1, в Test2 InErrors не соответствует RcvbufErrors и RcvbufErrors всегда равен нулю. Может кто-нибудь объяснить причину этого, пожалуйста?!? В чем же разница между InErrors и RcvbufErrors. Я понимаю RcvbufErrors, но не InErrors.

Спасибо за вашу помощь и время!!!

Ответы

Ответ 1

Настройка сетевого сетевого ядра Linux для снижения пакетов снижается, так как есть много параметров настройки от драйвера, вплоть до сетевого стека.

Я написал длинный пост , объясняющий все параметры настройки сверху вниз и объясняющие, что означает каждое из полей в /proc/net/snmp вы можете понять, почему эти ошибки происходят. Взгляните, я думаю, это должно помочь вам снизить вашу сеть до 0.

Ответ 2

Если на аппаратном уровне нет капель, то в основном речь должна идти о памяти, вы должны настроить параметры конфигурации ядра, чтобы достичь 0 капель (очевидно, вам нужно разумное сбалансированное оборудование для сетевого трафика, recv'ing).

Я думаю, что вам не хватает netdev_max_backlog, что важно для входящих пакетов:

Максимальное количество пакетов, поставленных в очередь на стороне INPUT, когда интерфейс получает пакеты быстрее, чем ядро, может обрабатывать их.

Ответ 3

InErrors состоит из:

  • поврежденные пакеты (неправильные заголовки или контрольная сумма)
  • полный размер буфера RCV

Итак, я предполагаю, что вы исправили проблему переполнения буфера (RcvbufErrors - 0), а оставшиеся - это пакеты с неправильными контрольными суммами.