Indy OnExecute сначала Читать медленно - PullRequest
0 голосов
/ 16 февраля 2011

В моем OnExecute в C ++ Builder XE есть следующий код:

void __fastcall Test::TestExecute( TIdContext* AContext )
{
   try
   {
      // get the command directive
      DWORD startTime = timeGetTime( );
      UnicodeString DBCommand = AContext->Connection->IOHandler->ReadChar();
      DWORD endTime = timeGetTime();
      UnicodeString log;
      log.printf( L"getting command %d ms", endTime - startTime );
      Log( log );
      ...

Журнал начинается с получения команды 100 миллисекунд и переходит к 300, где он находится до конца работы приложения. Я думал, что OnExecute был вызван, когда данные были в буфере, так почему бы потребовалось от 100 до 300 мсек для успешного первого чтения?

После этого первого чтения в том же OnExecute все остальные данные читаются очень очень быстро (от миллисекунды до субмиллисекунды).

Что может быть не так?

EDIT:

при запуске метода: AContext->Connection->IOHandler->InputBuffer->Size равно 0. После первого чтения возвращается AContext->Connection->IOHandler->InputBuffer->Size содержит то, что осталось в буфере после чтения. Таким образом, это означает, что OnExecute вызывается до того, как какие-либо данные будут фактически доступны вызывающей стороне. Таким образом, 100-300 мс - это количество времени, которое требуется Indy для извлечения данных из сокета и помещения их в буфер после получения уведомления о поступлении данных. Это кажется слишком длинным.

EDIT:

удалено do{, поскольку это подразумевало петлю, которой там не было.

1 Ответ

0 голосов
/ 16 февраля 2011

Событие OnExecute вообще не связано с буфером сокета. TIdTCPServer начинает вызывать OnExecute сразу после вызова события OnConnect и продолжает вызывать OnExecute в бесконечном цикле, пока клиент не отключится (другими словами, вы НЕ должны зацикливаться внутри обработчика OnExecute . Прочитать пакет, обработать, выйти, дождаться следующего события, повторить).

Вы правы, что InputBuffer может вырасти больше, чем вы запрашиваете в коде. Все методы чтения IOHandler получают свои данные только от InputBuffer, а не от сокета напрямую. Если у InputBuffer недостаточно кэшированных байтов для удовлетворения запроса на чтение, IOHandler будет ожидать появления байтов в сокете, а затем будет считывать все байты в InputBuffer для последующего использования. Это минимизирует частоту доступа к сокету и помогает адаптировать сокет к новым данным.

...