如何使用IdTCPClient从服务器等待字符串? [英] How can I wait for a string from a server with IdTCPClient?
问题描述
我有一个IdTelnet(indy 10.1)的问题。我无法以Unicode模式从服务器读取数据。现在我想用IdTCPClient编写telnet终端。
I have a problem with IdTelnet (indy 10.1). I can't read the data from a server in Unicode mode. and now I want to write the telnet terminal with IdTCPClient.
服务器有时发送一行,有时候会发送越来越多的行。但是发送之间没有固定的时间。
The server sometimes send one line and sometimes more and more lines. But there is not a fixed time between sending.
现在我的问题是,当我必须从InBuffer读取数据。
Now my problem is that when I must read data from InBuffer.
或者当我必须使用ReadLn函数从服务器读取数据时,必须运行多少次ReadLn?
Or when I must use the ReadLn function to read the data from the server, how many times must I run the ReadLn?
推荐答案
TIdTelnet
是一个多线程组件。它有一个内部线程,从套接字连续读取,每当数据缓冲区可用时触发 TIdTelnet.OnDataAvailable
事件。
TIdTelnet
is a multithreaded component. It has an internal thread that continuously reads from the socket, firing the TIdTelnet.OnDataAvailable
event whenever a buffer of data is available.
TIdTelnet
是一个 TIdTCPClient
后裔。查看IdTelnet.pas源文件,看看它是如何实现的。您可以在自己的代码中执行类似的操作,在您自己的线程中调用 TIdIOHandler.ReadLn()
,例如:
TIdTelnet
is a TIdTCPClient
descendant. Look in the IdTelnet.pas source file to see how it is implemented. You can do something similar in your own code, calling TIdIOHandler.ReadLn()
in your own thread, eg:
type
TMyThread = class(TThread)
private
FConn: TIdTCPConnection;
protected
procedure Execute; override;
public
constructor Create(AConn: TIdTCPConnection); reintroduce;
end;
constructor TMyThread.Create(AConn: TIdTCPConnection);
begin
inherited Create(False);
FConn := AConn;
end;
procedure TMyThread.Execute;
var
S: String;
begin
while not Terminated do
begin
S := FConn.IOHandler.ReadLn(...);
...
end;
end;
var
Thread: TMyThread = nil;
procedure TForm1.ConnectButtonClick(Sender: TObject);
begin
IdTCPClient1.Connect;
try
Thread := TMyThread.Create(IdTCPClient1);
except
IdTCPClient1.Disconnect;
raise;
end;
end;
procedure TForm1.DisconnectButtonClick(Sender: TObject);
begin
if Assigned(Thread) then Thread.Terminate;
try
IdTCPClient1.Disconnect;
finally
if Assigned(Thread) then
begin
Thread.WaitFor;
FreeAndNil(Thread);
end;
end;
end;
如果不想使用线程,可以使用计时器。为了确保您的定时器线程(如主线程)不被不必要地被阻止,只要 TIdIOHandler.CheckForDataOnSource()
> TIdIOHandler.InputBuffer 是空的,然后在数据可用之前调用 TIdIOHandler.ReadLn()
,例如:
If you don't want to use a thread, then you can use a timer instead. To make sure your timer thread (such as the main thread) is not blocked unnecessarily, use the TIdIOHandler.CheckForDataOnSource()
method with a small timeout whenever the TIdIOHandler.InputBuffer
is empty, before then calling TIdIOHandler.ReadLn()
only when data is available, eg:
procedure TForm1.ConnectButtonClick(Sender: TObject);
begin
IdTCPClient1.Connect;
ReadTimer.Enabled := True;
end;
procedure TForm1.DisconnectButtonClick(Sender: TObject);
begin
ReadTimer.Enabled := False;
IdTCPClient1.Disconnect;
end;
procedure TForm1.ReadTimerElapsed(Sender: TObject);
var
S: String;
begin
if IdTCPClient1.IOHandler.InputBufferIsEmpty then
begin
IdTCPClient1.IOHandler.CheckForDataOnSource(10);
if IdTCPClient1.IOHandler.InputBufferIsEmpty then Exit;
end;
S := IdTCPClient1.IOHandler.ReadLn(...);
...
end;
这篇关于如何使用IdTCPClient从服务器等待字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!