Indy onexecure a d'abord lu lent
-
14-11-2019 - |
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à.
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 IOHandler
Les 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.