7

Delphi 2009 で提供されている Indy 10 をいじっていて、OnExecute が起動したときに IOHandler からすべてのデータを取得するのに問題があります...

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 は信頼性が低く、多くの場合 0 を返しますが、次に OnExecute を実行すると正しいバイト数が取得されますが、それでは遅すぎます。

基本的に、すべてのデータを取得し、それを UTF8String ( Unicode 文字列ではない) に詰め込み、特別なマーカーを解析できるようにしたいと考えています。したがって、ヘッダーはなく、メッセージは可変長です。Indy 10 IOHandlers がこのためにセットアップされていないか、間違って使用しているようです。

特定のサイズのバッファを渡し、可能な限りいっぱいにして、実際にいっぱいになったバイト数を返し、それ以上ある場合は続行するなどのことを行うとよいでしょう。

余談ですが、TIdSchedulerOfFiber のステータスはどうなっているのでしょうか。これは非常に興味深いようですが、機能しますか? 誰かがそれを使用していますか?ただし、Delphi 2009 の標準インストールには含まれていません。

更新: Msg := AContext.Connection.IOHandler.ReadLn(#0, enUTF8); が見つかりました。これは機能しますが、上記の質問に対する答えを知りたいのですが、IO のブロックに基づいているためですか? これにより、この TIdSchedulerOfFiber がさらに熱心になります。

4

2 に答える 2

17

そのように Readable() を使用するべきではありません。代わりに次のことを試してください。

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;

または:

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;

TIdSchedulerOfFiber に関しては、現時点で SuperCore パッケージは事実上死んでいます。非常に長い間作業が行われておらず、最新の Indy 10 アーキテクチャに対応していません。後日復活を試みるかもしれませんが、近い将来の計画にはありません。

于 2009-02-13T02:07:31.533 に答える
1
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; 
于 2011-05-11T11:32:52.907 に答える