Delphi 2009, Indy 10, TIdTCPServer.OnExecute, comment saisir tous les octets dans le InputBuffer

StackOverflow https://stackoverflow.com/questions/544204

  •  23-08-2019
  •  | 
  •  

Question

Je suis de déconner avec l'Indy 10 fourni avec Delphi 2009 et ai du mal à obtenir toutes les données de la IOHandler quand OnExecute incendies ...

procedure TFormMain.IdTCPServerExecute(AContext: TIdContext);
var
  RxBufStr: UTF8String;
  RxBufSize: Integer;
begin

  if AContext.Connection.IOHandler.Readable then
  begin
    RxBufSize := AContext.Connection.IOHandler.InputBuffer.Size;
    if RxBufSize > 0 then
    begin
      SetLength(RxBufStr, RxBufSize);
      AContext.Connection.IOHandler.ReadBytes(TBytes(RxBufStr), RxBufSize, False);
    end;
  end;

end;

AContext.Connection.IOHandler.InputBuffer.Size ne semble pas fiable et retourne souvent 0, mais sur la prochaine course throug le OnExecute il va prendre le bon nombre d'octets, mais trop tard.

Essentiellement, je veux être en mesure de saisir simplement toutes les données, le farcir dans un UTF8String ( pas une chaîne Unicode), puis analyser pour un marqueur spécial. Donc, je n'ai pas en-têtes et les messages sont de longueur variable. Il semble que les Indy 10 IOHandlers ne sont pas configuré pour cela ou je suis juste en utilisant mal.

Il serait bien de faire quelque chose comme passer un tampon d'une certaine taille, remplir autant que possible et renvoyer le nombre d'octets remplis puis continuer s'il y a plus.

En aparté ce qui est de l'état TIdSchedulerOfFiber, cela semble très intéressant, ça marche? Quelqu'un est-il l'utiliser? Je remarque que ce n'est pas dans la norme de l'installation Delphi 2009 cependant.

Mise à jour: J'ai trouvé Msg: = AContext.Connection.IOHandler.ReadLn (# 0, enUTF8); qui fonctionne, mais je voudrais encore connaître la réponse à la question ci-dessus, est-ce parce qu'elle est basée sur le blocage IO? Ce qui rend encore plus vif sur cette TIdSchedulerOfFiber.

Était-ce utile?

La solution

Vous ne devriez pas utiliser Readable () comme ça. Essayez ce qui suit à la place:

procedure TFormMain.IdTCPServerExecute(AContext: TIdContext);
var
  RxBuf: TIdBytes;
begin
  RxBuf := nil;
  with AContext.Connection.IOHandler do
  begin
    CheckForDataOnSource(10);
    if not InputBufferIsEmpty then
    begin
      InputBuffer.ExtractToBytes(RxBuf);
      // process RxBuf as needed...
    end;
  end;
end;

Vous pouvez également:

procedure TFormMain.IdTCPServerExecute(AContext: TIdContext);
var
  RxBufStr: String; // not UTF8String
begin
  with AContext.Connection.IOHandler do
  begin
    CheckForDataOnSource(10);
    if not InputBufferIsEmpty then
    begin
      RxBufStr := InputBuffer.Extract(-1, enUtf8);

      // Alternatively to above, you can set the
      // InputBuffer.Encoding property to enUtf8
      // beforehand, and then call TIdBuffer.Extract()
      // without any parameters.
      //
      // Or, set the IOHandler.DefStringEncoding
      // property to enUtf8 beforehand, and then
      // call TIdIOHandler.InputBufferAsString()

      // process RxBufStr as needed...
    end;
  end;
end;

En ce qui concerne TIdSchedulerOfFiber - le paquet SuperCore est effectivement mort à ce moment. Il n'a pas été travaillé dans un temps très long, et n'est pas mise à jour avec la dernière architecture Indy 10. Nous pouvons essayer de ressusciter à une date ultérieure, mais ce n'est pas dans nos plans pour l'avenir proche.

Autres conseils

procedure TFormMain.IdTCPServerExecute(AContext: TIdContext); 
var
  RxBufStr: UTF8String;
  RxBufSize: Integer;
begin    
  if AContext.Connection.IOHandler.Readable then
  begin     
    AContext.Connection.IOHandler.ReadBytes(TBytes(RxBufStr),-1, False);
  end;
end; 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top