Я написал простую программу 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%, как было сказано выше.
Следовательно, чтобы уменьшить потерю пакетов, я пробовал:
- Увеличен приоритет моей выборки с помощью renice.
- Увеличенный размер буфера приема (как на уровне системы, так и на уровне процесса)
Повысьте приоритет до -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.
Спасибо за вашу помощь и время!!!