Я написал простую программу UDP Server, чтобы лучше понять возможные узкие места в сети.
Сервер UDP: создает сокет UDP, связывает его с указанным портом и адресом и добавляет дескриптор файла сокета в список интересов epoll. Затем его epoll ждет входящего пакета. При получении входящего пакета (EPOLLIN) он читает пакет и просто печатает длину принятого пакета. Довольно просто, правда :)
Клиент UDP: я использовал hping, как показано ниже:
hping3 192.168.1.2 --udp -p 9996 --flood -d 100
Когда я отправляю пакеты udp со скоростью 100 пакетов в секунду, я не обнаруживаю потери пакетов UDP. Но когда я заполняю пакеты udp (как показано в приведенной выше команде), я вижу значительную потерю пакетов.
Test1: когда 26356 пакетов передаются от клиента UDP, моя примерная программа получает ТОЛЬКО 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 ethX" как на стороне клиента, так и на стороне сервера, в то время как на уровне приложения я вижу потерю 53%, как сказано выше.
Следовательно, чтобы уменьшить потерю пакетов, я попробовал следующее:
- Увеличил приоритет моей демонстрационной программы, используя renice.
- Увеличен размер буфера приема (как на уровне системы, так и на уровне процесса)
Увеличьте приоритет до -20:
renice -20 2022
2022 (идентификатор процесса) старый приоритет 0, новый приоритет -20
Увеличьте размер буфера приема до 16 МБ:
На уровне процесса:
int sockbufsize = 16777216;
setsockopt (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: когда 1985076 пакетов передаются от клиента UDP, моя примерная программа получает 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.
Спасибо за помощь и время !!!