Буфер ASIO не работает - PullRequest
       27

Буфер ASIO не работает

5 голосов
/ 17 ноября 2010

Я пишу сетевое приложение, которое использует ASIO / UDP для отправки и получения между одной парой удаленных / локальных конечных точек.Я использовал udp :: socket :: receive для получения данных, и все в моем коде работало логически, но я терял огромное количество пакетов.Я обнаружил, что любой пакет, полученный, но не заблокированный функцией приема, был потерян - это не буферизация.Это было особенно странно, потому что я установил приемный буфер на 2 МБ, используя следующую команду:

sock_udp.connect( remote_endpoint );
sock_udp.set_option( boost::asio::socket_base::receive_buffer_size(2*1024*1024) );

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

Я подумал, что это, возможно, ошибка с udp :: socket :: receive, поэтому я переписал свой сетевой код для использования udp::socket::async_receive, но у меня все еще естьта же проблема.То есть, как только мой обработчик вызывается, я отбрасываю любые пакеты, пока я не вызову async_receive снова.

Я что-то принципиально неправильно понимаю?Есть ли другой подход, который я должен использовать для повышения, чтобы буферизовать входящие пакеты?

Если это поможет, я убедился, что это происходит как в OS X в XCode, используя их собственную сборку gcc4.2, так иUbuntu 10.10 с использованием gcc4.5.Я еще не смог попробовать это в Windows.

1 Ответ

2 голосов
/ 17 ноября 2010

Общая идея здесь заключается в том, что ваша программа должна тратить подавляющее большинство своего времени на ожидание в сокете, чтобы доставить что-либо, либо заблокированное при получении UDP, либо в io_service для уведомления о том, что сокет получил что-то асинхронно. Сокет неявно имеет в ОС небольшой буфер для приема пакетов, и избежать этого невозможно. Так что проблема, скорее всего, в том, как ведет себя ваша программа.

  • Ваш поток где-нибудь, кроме ASIO io_service? Если это так, вы можете легко переполнить любой буфер сокета.
  • Можете ли вы доказать, что в среднем время между блокировкой вызовов меньше, чем время между отправляемыми пакетами?
  • Вы должны снова вызвать async_receive после получения данных из сокета. Например, вы можете запустить другой async_receive из вашего обработчика получения.
...