Question

I have the following code in my OnExecute in 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 );
      ...

The log starts at getting command 100 milliseconds and creeps to 300 where it sits for the rest of the application run. I thought that OnExecute was called once data was in the buffer, so why would it take 100 to 300 ms for the first read to succeed?

After this first read in the same OnExecute all other data is read very very quickly (millisecond to sub millisecond).

What could be going wrong?

EDIT:

at method launch: AContext->Connection->IOHandler->InputBuffer->Size is 0. After the first read returns AContext->Connection->IOHandler->InputBuffer->Size contains whats left int he buffer after the read. So this implies that OnExecute is called before any data is actually available to the caller. So the 100-300 ms is the amount of time its taking Indy to fetch the data from the socket and place it in the Buffer after it get notification that data is arriving. That seems way too long.

EDIT:

removed do{ as it was implying a loop that was not there.

Was it helpful?

Solution

The OnExecute event is not tied to the socket buffer at all. TIdTCPServer begins calling OnExecute immeidately after the OnConnect event is called, and continues calling OnExecute in an endless loop until the client disconnects (in other words, you should NOT be looping yourself inside of your OnExecute handler. Read a packet, process, exit, wait for the next event, repeat).

You are correct that the InputBuffer can grow larger than what you are asking for in code. All of the IOHandler's reading methods get their data from the InputBuffer only, not the socket directly. If the InputBuffer does not have enough bytes cached to satisfy a read request, the IOHandler will then wait for bytes to be available on the socket, and will then read all of the bytes into the InputBuffer for later use. This minimizes how often the socket needs to be accessed, and help keep the socket responsive to new data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top