0

モバイル アプリとデスクトップ アプリケーションの開発に Delphi XE8 を使用しています。モバイル アプリケーションでは TIDtcpClient コンポーネントを使用し、デスクトップ アプリケーション アプリケーションでは TServerSocket を使用しています。

サーバー デスクトップ アプリケーションには、約 1500 のレコードを含む TList が含まれています。Client Mobile アプリケーションでこれらの値を取得するために、次の方法を使用しています。

  1. まず、ダウンロード リクエストがクライアント モバイル アプリからサーバー アプリケーションに送信されます。
  2. 次に、10 件のレコードを取得し、クライアント モバイル アプリケーションに送り返します。この後、Client List の値を更新し、再びサーバー アプリにリクエストを送り返します。
  3. レコード数に達するまで、このプロセスが続行されます。

問題は、この方法に従っている場合、ほぼ 2 分かかり、すべてのデータを適切に取得していることです。そこで、ファイル ストリーム方式を使用することにしました。以下にサンプルコードを記載しました。

サーバー側アプリ:

//first saved the List into FileStream & it is working as I have reloaded and checked
//So again I'm loading the saved file, The file Size is near to 400KB
FileStream := TFileStream.Create('D:\ListDet.dat', mtfmOpenRead);
Socket.SendStream(FileStream);

クライアント側のモバイル アプリ:

var 
  FileS: TFileStread;
  i: Size;
begin
//Inside the thread
  TiDTcpClient.IOHandler.ReadStream(FileS, i);
end;

上記の方法を使用していると、例外が発生し、データを取得できません。

サーバーからクライアントにデータをより速く取得するための解決策を教えてください。

4

1 に答える 1

0

問題は、この方法に従っている場合、ほぼ 2 分かかり、すべてのデータを適切に取得していることです。

その状況でデータを送信するために使用していた実際の I/O メソッドを示したり説明したりしませんでした。

そのため、ファイル ストリーム メソッドを使用することにしました...そして、上記のメソッドを使用しているときに、[クライアント アプリ (モバイル) で正常に例外が閉じられました] が発生し、データを取得できません。

TCustomWinSocket.SendStream()コンテンツをそのまま送信するだけで、TStream他には何も送信しません。

初期化されていない変数iを に渡していますTIdIOHandler.ReadStream()。そのパラメーターはReadStream()、読み取るバイト数を示します。は初期化されていないためi、その値は、その時点でたまたまスタック上にあるランダム データです。

i実行時に発生した場合、それは読み取りを試みる> 0バイト数です。ReadStream()その数のバイトが実際に送信されない場合、は、経過時間 (デフォルトでは無限) またはソケットが切断されるReadStream()まで、さらにバイトを待機する呼び出しスレッドをブロックします。ReadTimeout

iたまたま正確な場合-1(AReadUntilDisconnectパラメータはデフォルトで False です)、ソケットから/ (プロパティに応じて)ReadStream()を読み取ろうとし、それをバイト数として使用してストリームの残りの読み取りを終了します。 はそのようなサイズ値を送信していません。IntegerInt64TIdIOHandler.LargeStreamTCustomWinSocket.SendStream()

の場合iは、バイト カウントを無視し、ソケットが切断される (強制的に True になる)< 0まで読み取りを続けます。ReadStream()AReadUntilDisconnect

のデフォルトの動作はTIdIOHandler.ReadStream()、ストリーム データの前にストリーム サイズが続くことを想定していますが、初期化されていないi変数を渡すことでその動作をオーバーライドしているため、動作は未定義です。

サーバーはストリーム データを送信する前にストリーム サイズを送信していないため、ストリームを送信した後にソケットを切断しない限り、クライアントは予想されるバイト数を知る方法がありません。

于 2015-06-27T01:31:25.860 に答える