1

フロントエンドレイヤーとしてPHPと通信するサーバーデーモン(Linux、Ubuntu)を作成しました。

最近、FPCとIndyライブラリの両方をFPC 2.6.0に更新し、Indyをトランクバージョンに更新しました(Tiburonブランチを使用する前)。

すべてコンパイルされ、すべて正常に見えましたが、IOHandlerに書き込むときに、(PHPクライアントによって)何も受信されない場合、クライアントは0バイトが受信されたことを報告します。

問題を詳しく調べた後、IOHandlerのwriteメソッドを使用すると、IdGlobal.pasのToBytes()メソッドで、応答が送信される前にエンコーディングが検証および変換されることがわかりました。

ここで、ToBytes()ルーチンの変換行をコメントアウトすると、

if ASrcEncoding <> ADestEncoding then begin
  LBytes := TIdTextEncoding.Convert(ASrcEncoding, ADestEncoding, LBytes);

今回は、PHPクライアントが応答を受け取ります。

私の質問は、データのエンコードを停止するようにIndy tcpサーバーまたはIOHandlerを構成するにはどうすればよいですか?

4

1 に答える 1

1

IndyはTIdTextEncoding.Convert()、2つのエンコーディングが異なると判断したときに呼び出し、バイトを1つの文字セットから別の文字セットに変換できるようにします。TIdTextEncodingただし、Indyは、2つのオブジェクトが同じ文字セットを表す場合をまだ検出しないため、変換をスキップできます。これは主に、Delphi 2009-XEでのEmbarcaderoのクラスの制限によるもので、SysUtils.TEncodingその情報は公開されません(Delphi XE2では、TEncoding新しいプロパティを受け取りましEncodingNameCodePageが、Indyはそれらを利用するように更新されていません)。IndyのTIdTextEncodingクラスはDelphi2009+のエイリアスであり、Indyのコードページ全体で単一のAPIを維持するために、Delphi5-2007およびFreePascalでTEncodingモデル化されています。TEncoding

Indyは現在、TIdTextEncodingオブジェクトポインタを相互に比較するだけです。これは、TIdTextEncodingクラスプロパティの標準エンコーディングを使用する場合に問題ありません。これは、オブジェクトがメモリ内のシングルトンオブジェクトとして実装されているためです。ただし、Indyの関数などTIdTextEncoding、メソッドによって取得されたオブジェクトを混在させると、文字セットが一致したとしても、オブジェクトポインタは一致しません。理想的な条件では、それは文字セットからUnicodeへのno-op変換であり、同じ文字セットに戻ります。TIdTextEncoding.GetEncoding()CharsetToEncoding()

ただし、FreePascalTIdTextEncodingでは、ICONVライブラリを使用しており、IndyのICONVサポートは不完全です。変換は実装されていますが、完全なエラー処理はまだ実装されていません。これは主にerrno、ICONVが拡張エラーレポートに使用するさまざまなプラットフォームでの変数へのアクセスに関する問題が原因です。ICONVのエラーのすべてが致命的であるわけではありませんが、Indyはまだそれらを検出できません。

さらに悪いことに、TEncodingバッファエラーが発生した場合にのみ、変換エラーが発生したときに例外をスローしないように設定されています(そのためのEmbarcaderoの恥)。データ変換エラーが発生した場合は、TEncoding空のデータを返すだけです。TIdTextEncodingFreePascalなどのD2009+以外の環境では、この動作を維持する必要がありました。Indyを更新して、その状態を内部でチェックし、必要に応じて独自の例外を発生させることができると思います。

あなたの質問に答えるために、Indyにへの呼び出しをスキップするように指示するためにできることは何もありませんTIdTextEncoding.Convert()。とりあえずコメントアウトしてIndyを再コンパイルする必要があります。これは現在のIndyリリースの既知の問題であり、これに対処するためにいくつかの作業が行われていますが、いつ公開されるかについてはまだETAがありません。Indy 11ではTEncoding、少なくとも一般的に使用される文字セットについては、Indyでネイティブに独自の文字セットエンジンのサポートを終了して実装する可能性があります。そうすれば、特定のプラットフォーム固有のAPIに縛られることはなくなります。しかし、私たちはまだIndy 11の作業を開始しておらず、その機能セットがどうなるかさえ決定していません。

于 2012-03-30T19:49:32.237 に答える