문제

C++ Builder XE의 OnExecute에 다음 코드가 있습니다.

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~300ms가 걸리나요?

이 내용을 먼저 읽은 후 OnExecute 다른 모든 데이터는 매우 빠르게 읽혀집니다(밀리초에서 밀리초 미만).

무엇이 잘못될 수 있나요?

편집하다:

메소드 실행 시: AContext->Connection->IOHandler->InputBuffer->Size 0입니다.첫 번째 읽기가 반환된 후 AContext->Connection->IOHandler->InputBuffer->Size 읽은 후 버퍼에 남은 내용을 포함합니다.그래서 이것은 다음을 의미합니다. OnExecute 호출자가 실제로 데이터를 사용할 수 있기 전에 호출됩니다.따라서 100-300ms는 Indy가 소켓에서 데이터를 가져와서 데이터가 도착했다는 알림을 받은 후 버퍼에 저장하는 데 걸리는 시간입니다.너무 긴 것 같습니다.

편집하다:

제거됨 do{ 존재하지 않는 루프를 암시했기 때문입니다.

도움이 되었습니까?

해결책

그만큼 OnExecute 이벤트는 소켓 버퍼에 전혀 연결되어 있지 않습니다. TIdTCPServer 전화를 걸기 시작한다 OnExecute 그 직후에 OnConnect 이벤트가 호출되고 계속 호출됩니다. OnExecute 클라이언트 연결이 끊어질 때까지 무한 루프를 반복합니다. 즉, 클라이언트 내부에서 자신을 루프해서는 안 됩니다. OnExecute 매니저.패킷을 읽고, 처리하고, 종료하고, 다음 이벤트를 기다리는 과정을 반복합니다.

당신 말이 맞아요 InputBuffer 코드에서 요구하는 것보다 더 커질 수 있습니다.모든 IOHandler의 읽기 방법은 다음에서 데이터를 가져옵니다. InputBuffer 단, 소켓을 직접 연결하는 것은 아닙니다.만약 InputBuffer 읽기 요청을 충족할 만큼 캐시된 바이트가 충분하지 않은 경우 IOHandler 그런 다음 소켓에서 바이트를 사용할 수 있을 때까지 기다린 다음 모든 바이트를 소켓으로 읽습니다. InputBuffer 나중에 사용하기 위해.이렇게 하면 소켓에 액세스해야 하는 빈도가 최소화되고 소켓이 새 데이터에 응답하도록 유지하는 데 도움이 됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top