c ++ отбрасывает пакеты udp с помощью recvmmsg - PullRequest
0 голосов
/ 12 апреля 2019

Я занимаюсь разработкой программы на 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. Это не вариант для данного конкретного приложения. Спасибо.

1 Ответ

2 голосов
/ 12 апреля 2019

Увеличение размера приемного буфера для принимающего сокета должно решить эту проблему:

setsockopt (fd, IPPROTO_UDP, SO_RCVBUF, desired_receive_buffer_size);

Документация здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...