转载 DELPHI里INDY TCPClient的接收方法
新建一个package,把这个文件加入进去,然后编译安装,在你的组件面板里面会出现一个
ldx组件页,使用里面的TLdxTCPClient组件里的DataAvailable事件,看看效果吧,good luck!
View Code
unit LdxTCPClient;
interface
uses
Classes, SysUtils, IdGlobal, IdStack, IdTCPClient, IdTCPConnection;
type
TTCPClientReader = class;
TLdxTCPClient = class(TIdTCPClient)
private
FTCPClientReader: TTCPClientReader;
FOnDataAvailable: TNotifyEvent;
procedure DoDataAvailableEvent;
public
procedure Connect(const ATimeout: Integer = IdTimeoutDefault); override;
procedure Disconnect; override;
published
property OnDataAvailable: TNotifyEvent read FOnDataAvailable write FOnDataAvailable;
end;
TTCPClientReader = class(TThread)
protected
FTCPClient: TLdxTCPClient;
InpLastSize: Integer;
public
constructor Create(LdxTCPClient: TLdxTCPClient);
procedure Execute; override;
end;
procedure Register;
implementation
{ TTCPClient }
procedure TLdxTCPClient.Connect(const ATimeout: Integer);
begin
inherited Connect(ATimeout);
if Connected then
FTCPClientReader := TTCPClientReader.Create(Self);
end;
procedure TLdxTCPClient.Disconnect;
begin
if Assigned(FTCPClientReader) then FTCPClientReader.Terminate;
inherited Disconnect;
end;
procedure TLdxTCPClient.DoDataAvailableEvent;
begin
if Assigned(FOnDataAvailable) then FOnDataAvailable(Self);
end;
{ TTCPClientReader }
constructor TTCPClientReader.Create(LdxTCPClient: TLdxTCPClient);
begin
inherited Create(False);
InpLastSize := 0;
FTCPClient := LdxTCPClient;
FreeOnTerminate := True;
end;
procedure TTCPClientReader.Execute;
var
InpSize: Integer;
begin
while (not Terminated) and (FTCPClient.Connected) do
begin
try
InpSize := FTCPClient.InputBuffer.Size;
if (InpSize = 0) or (InpSize = InpLastSize) then
InpLastSize := InpSize + FTCPClient.ReadFromStack(False, -1, False);
FTCPClient.CheckForDisconnect(False, True);
if FTCPClient.Connected then
Synchronize(FTCPClient.DoDataAvailableEvent);
except
if FTCPClient.Connected then FTCPClient.Disconnect;
Terminate;
end;
end;
end;
procedure Register;
BEGIN
RegisterComponents('LDX',[TLdxTCPClient]);
END;
end.
interface
uses
Classes, SysUtils, IdGlobal, IdStack, IdTCPClient, IdTCPConnection;
type
TTCPClientReader = class;
TLdxTCPClient = class(TIdTCPClient)
private
FTCPClientReader: TTCPClientReader;
FOnDataAvailable: TNotifyEvent;
procedure DoDataAvailableEvent;
public
procedure Connect(const ATimeout: Integer = IdTimeoutDefault); override;
procedure Disconnect; override;
published
property OnDataAvailable: TNotifyEvent read FOnDataAvailable write FOnDataAvailable;
end;
TTCPClientReader = class(TThread)
protected
FTCPClient: TLdxTCPClient;
InpLastSize: Integer;
public
constructor Create(LdxTCPClient: TLdxTCPClient);
procedure Execute; override;
end;
procedure Register;
implementation
{ TTCPClient }
procedure TLdxTCPClient.Connect(const ATimeout: Integer);
begin
inherited Connect(ATimeout);
if Connected then
FTCPClientReader := TTCPClientReader.Create(Self);
end;
procedure TLdxTCPClient.Disconnect;
begin
if Assigned(FTCPClientReader) then FTCPClientReader.Terminate;
inherited Disconnect;
end;
procedure TLdxTCPClient.DoDataAvailableEvent;
begin
if Assigned(FOnDataAvailable) then FOnDataAvailable(Self);
end;
{ TTCPClientReader }
constructor TTCPClientReader.Create(LdxTCPClient: TLdxTCPClient);
begin
inherited Create(False);
InpLastSize := 0;
FTCPClient := LdxTCPClient;
FreeOnTerminate := True;
end;
procedure TTCPClientReader.Execute;
var
InpSize: Integer;
begin
while (not Terminated) and (FTCPClient.Connected) do
begin
try
InpSize := FTCPClient.InputBuffer.Size;
if (InpSize = 0) or (InpSize = InpLastSize) then
InpLastSize := InpSize + FTCPClient.ReadFromStack(False, -1, False);
FTCPClient.CheckForDisconnect(False, True);
if FTCPClient.Connected then
Synchronize(FTCPClient.DoDataAvailableEvent);
except
if FTCPClient.Connected then FTCPClient.Disconnect;
Terminate;
end;
end;
end;
procedure Register;
BEGIN
RegisterComponents('LDX',[TLdxTCPClient]);
END;
end.