Question

J'ai le code suivant dans mon OneXecute dans 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 );
      ...

Le journal commence à obtenir la commande de 100 millisecondes et se glisse à 300 où il se trouve pour le reste de l'application. Je pensais que OnExecute A été appelé une fois que les données étaient dans le tampon, alors pourquoi prendrait-il 100 à 300 ms pour que la première lecture réussisse?

Après cette première lecture dans la même chose OnExecute Toutes les autres données sont lues très très rapidement (millisecondes à sous-milliseconde).

Qu'est-ce qui pourrait mal passer?

ÉDITER:

Au lancement de la méthode: AContext->Connection->IOHandler->InputBuffer->Size est 0. après la première lecture revient AContext->Connection->IOHandler->InputBuffer->Size Contient ce qui reste dans le tampon après la lecture. Donc cela implique que OnExecute est appelé avant que toute donnée soit réellement disponible pour l'appelant. Ainsi, le 100-300 ms est le temps qu'il prend Indy pour récupérer les données de la prise et la placer dans le tampon après avoir obtenu la notification que les données arrivent. Cela semble beaucoup trop long.

ÉDITER:

supprimé do{ car il impliquait une boucle qui n'était pas là.

Était-ce utile?

La solution

La OnExecute L'événement n'est pas du tout lié au tampon de douille. TIdTCPServer commence à appeler OnExecute imméidément après le OnConnect L'événement est appelé et continue d'appeler OnExecute Dans une boucle sans fin jusqu'à ce que le client se déconnecte (en d'autres termes, vous ne devriez pas vous faire boucler à l'intérieur de votre OnExecute gestionnaire. Lisez un paquet, traitez, sortez, attendez le prochain événement, répétez).

Vous avez raison que le InputBuffer peut grandir plus que ce que vous demandez dans le code. La totalité de la IOHandlerLes méthodes de lecture de l'offre d'obtention de leurs données à partir du InputBuffer Seulement, pas la prise directement. Si la InputBuffer n'a pas assez d'octets mis en cache pour satisfaire une demande de lecture, le IOHandler Attendra ensuite que les octets soient disponibles sur la prise, puis liront tous les octets dans le InputBuffer pour une utilisation ultérieure. Cela minimise la fréquence à laquelle le socket doit être accessible et aide à maintenir la socket sensible aux nouvelles données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top