使用して、タイムアウトで一部のデータを受信:? はどのようにTIdTcpClientを使用して、以下の条件で100バイトの文字列を受け取るためにTIdTcpClient
- 何も入ってきていない場合は、読むの呼び出しはブロックされなければならないとスレッドが永遠に をお待ちしております
- 100バイトを受信した場合、Read呼び出しはバイト文字列を返す必要があります
- 0より大きいが100未満の値を受け取った場合、少なくとも何らかのタイムアウト(たとえば1秒)後にRead呼び出しが返されますDelphi IDEのデバッグモードでの例外処理がmになっていないため、タイムアウト例外を発生させることなく、妥当な時間便利です。
今の私の最適でないコードは次のとおりです。
unit Unit2;
interface
uses
System.Classes, IdTCPClient;
type
TTcpReceiver = class(TThread)
private
_tcpc: TIdTCPClient;
_onReceive: TGetStrProc;
_buffer: AnsiString;
procedure _receiveLoop();
procedure _postBuffer;
protected
procedure Execute(); override;
public
constructor Create(); reintroduce;
destructor Destroy(); override;
property OnReceive: TGetStrProc read _onReceive write _onReceive;
end;
implementation
uses
System.SysUtils, Vcl.Dialogs, IdGlobal, IdExceptionCore;
constructor TTcpReceiver.Create();
begin
inherited Create(True);
_buffer := '';
_tcpc := TIdTCPClient.Create(nil);
//_tcpc.Host := '192.168.52.175';
_tcpc.Host := '127.0.0.1';
_tcpc.Port := 1;
_tcpc.ReadTimeout := 1000;
_tcpc.Connect();
Suspended := False;
end;
destructor TTcpReceiver.Destroy();
begin
_tcpc.Disconnect();
FreeAndNil(_tcpc);
inherited;
end;
procedure TTcpReceiver.Execute;
begin
_receiveLoop();
end;
procedure TTcpReceiver._postBuffer();
var buf: string;
begin
if _buffer = '' then Exit;
buf := _buffer;
_buffer := '';
if Assigned(_onReceive) then begin
Synchronize(
procedure()
begin
_onReceive(buf);
end
);
end;
end;
procedure TTcpReceiver._receiveLoop();
var
c: AnsiChar;
begin
while not Terminated do begin
try
c := AnsiChar(_tcpc.IOHandler.ReadByte());
_buffer := _buffer + c;
if Length(_buffer) > 100 then
_postBuffer();
except
//Here I have to ignore EIdReadTimeout in Delphi IDE everywhere, but I want just to ignore them here
on ex: EIdReadTimeout do _postBuffer();
end;
end;
end;
end.
このハードワークを自分でやってみるのではなく、['IOHandler.ReadBytes()'](http://www.indyproject.org/docsite/html/[email protected]@[email protected]) ? –
@Paul Indyがバッファリングを処理するのは、ほとんどの人が管理したいと思っているよりも優れていると私は確信しています。 50バイトだけが必要な場合は、なぜ100を求めるのですか?ある時点では、有用な意味を持つことができる最小のパケットサイズがあります。そのパケットを待ってください。それが処理されたらそれを処理し、それがなければ何もしません。あなたが失われたデータを気にしないならば、おそらくUDPはTCPより良いプロトコルです。 –
@Paul盲目的に読んでから例外を処理しようとするよりも、読み込みを試みる前にバッファをチェックする方が良いでしょう( 'IOHandler.InputBufferIsEmpty then ...')。空のバッファから読み取ろうとしても意味がありません。文字列を読んでコマンドプロトコルを制御している場合は、分かりやすいコマンドターミネータを選び、 'ReadLn'を使うだけです。 –