Я создал программу клиент/сервер, клиент запускает экземпляр класса Writer, а сервер запускает экземпляр класса Reader. Затем устройство записи будет асинхронно записывать DATA_SIZE байт данных в устройство чтения каждые USLEEP миллисекунд.
Каждый последующий запрос async_write от Writer выполняется только в том случае, если был вызван обработчик «при записи» из предыдущего запроса.
Проблема в том, что если Writer (клиент) записывает в сокет больше данных, чем Reader (сервер) может получить, это похоже на поведение:
Writer начнет запись в (я думаю) системный буфер, и даже если данные еще не были получены Reader, он будет вызывать обработчик «при записи» без ошибки.
Когда буфер заполнен, boost::asio больше не будет запускать обработчик «при записи», пока буфер не станет меньше.
Тем временем Reader все еще получает небольшие порции данных.
Тот факт, что Reader продолжает получать байты после закрытия программы Writer, кажется, подтверждает правильность этой теории.
Чего мне нужно добиться, так это предотвратить эту буферизацию, потому что данные должны быть «в реальном времени» (насколько это возможно).
Я предполагаю, что мне нужно использовать некоторую комбинацию параметров сокета, которые предлагает asio, например, no_delay или send_buffer_size, но я просто предполагаю, поскольку мне не удалось поэкспериментировать с ними.
Я думаю, что первое решение, которое можно придумать, это использовать UDP вместо TCP. Это будет иметь место, так как в ближайшем будущем мне нужно будет переключиться на UDP и по другим причинам, но сначала я хотел бы узнать, как это сделать с TCP просто ради имея это прямо в моей голове на случай, если у меня будет аналогичная проблема в другой день в будущем.
ПРИМЕЧАНИЕ 1. До того, как я начал экспериментировать с асинхронными операциями в библиотеке asio, я реализовал тот же сценарий с использованием потоков, блокировок и asio::sockets и в то время не сталкивался с такой буферизацией. Мне пришлось переключиться на асинхронный API, потому что asio, похоже, не допускает временных прерываний синхронных вызовов.
ПРИМЕЧАНИЕ 2. Вот рабочий пример, демонстрирующий проблему: http://pastie.org/3122025< /а>
EDIT: я провел еще один тест, в своем ПРИМЕЧАНИЕ 1 я упомянул, что при использовании asio::iosockets у меня не было такой буферизации. Поэтому я хотел быть уверенным и создал этот тест: http://pastie.org/3125452 Оказывается, что < strong>событие буферизации с asio::iosockets, поэтому должно быть что-то еще, что заставило его работать гладко, возможно, более низкий FPS.