Я занимаюсь разработкой программы на c ++, которая потребляет поток данных UDP из FPGA через Ethernet. Между FPGA и моей сетевой картой нет концентратора или маршрутизатора. Данные - 10446 pps со скоростью 125350,0 кбит / с.
Мое приложение c ++ использует выделенный поток и recvmmsg для очистки данных. Каждый пакет имеет порядковый номер в качестве первых 4 байтов, за которыми следуют 1468 байтов потоковых данных. Я использую recvmmsg, и я попробовал VLEN
(10 100) и комбинации MSG_WAITFORONE
, MSG_DONTWAIT
, 0
для флагов.
Симптомы, которые я вижу, таковы:
- Перед запуском программы поток работает с фиксированной скоростью.
- Когда программа загружается, у меня короткий начальный период, когда возвращаемое значение
recvmmsg
совпадает с VLEN
. Если я правильно понимаю, это истощение буфера ядра Linux.
- После этого я всегда получаю значение
1
для возвращаемого значения recvmmsg
- Если я вызываю небольшую нагрузку на систему (например, изменение размера окна графического интерфейса). Я вижу падение пакетов UDP, на что указывают пропущенные порядковые номера. (не переупорядочено, просто отсутствует).
- Во время / после сброса я не получаю большее возвращаемое значение для
recvmmsg
- Wireshark / tcpdump не показывает пропущенных данных, присутствуют все порядковые номера.
Если я смотрю вывод netstat -suna
, я вижу увеличение значения RcvbufErrors:
.
Если я смотрю вывод ifconfig
, я не вижу пропущенных пакетов (RX packets:602492703 errors:0 dropped:0 overruns:0 frame:0
).
Вот мои вопросы:
- Почему я никогда не получаю более одного пакета из
recvmmsg
во время условия отбрасывания?
- Почему wireshark может захватывать пакеты, а мой c ++ не может?
- Какие инструменты я могу использовать, чтобы лучше понять, почему я бросаю?
Я попытался настроить следующие параметры:
sysctl -w net.core.netdev_max_backlog=10000
sysctl -w net.core.rmem_max=9926214400
Пожалуйста, не предлагайте мне переключиться на TCP. Это не вариант для данного конкретного приложения. Спасибо.