Indy OnExecute 먼저 읽기 느림
-
14-11-2019 - |
문제
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
나중에 사용하기 위해.이렇게 하면 소켓에 액세스해야 하는 빈도가 최소화되고 소켓이 새 데이터에 응답하도록 유지하는 데 도움이 됩니다.