Създадох програма клиент/сървър, клиентът стартира екземпляр на клас Writer, а сървърът стартира екземпляр на клас Reader. След това Writer ще записва DATA_SIZE байта данни асинхронно в Reader на всеки USLEEP мили секунди.
Всяка следваща заявка за async_write от Writer се извършва само ако манипулаторът "при запис" от предишната заявка е бил извикан.
Проблемът е, че ако Writer (клиентът) записва повече данни в сокета, отколкото Reader (сървърът) може да получи, това изглежда е поведението:
Writer ще започне да записва в (мисля) системен буфер и въпреки че данните все още не са получени от Reader, той ще извика манипулатора "on write" без грешка.
Когато буферът е пълен, 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
РЕДАКТИРАНЕ: Направих още един тест, в моята ЗАБЕЛЕЖКА 1 споменах, че когато използвах asio::iosockets, не изпитвах това буфериране. Затова исках да съм сигурен и създадох този тест: http://pastie.org/3125452 Оказва се, че < strong>събитието за буфериране е налице с asio::iosockets, така че трябва да е имало нещо друго, което е причинило гладкото протичане, вероятно по-нисък FPS.