如何设置 Indy 自定义 TIdIOHandler?
How to setup an Indy custom TIdIOHandler?
我想为我的 Indy TCP 客户端使用自定义 TIdIOHandler
,但我不知道如何设置它。我创建了一个新的 IOHandler class,我注册了 TIdIOHandler.RegisterIOHandler
,然后我使用 TIdTCPClient.CreateIOHandler
和我的新处理程序引用。现在,当我尝试写入 TIdTCPClient.Socket
时,出现“抽象错误”异常......除了我的示例之外,我还需要配置其他东西吗?
TIdEnhancedIOHandler = class(TIdIOHandlerSocket)
public
function Acknowledge(Command: Cardinal = 0): Boolean;
end
{this is a client in a thread}
constructor TMyTCPClient.Create(const AHost: String; APort: Word);
begin
inherited Create;
FreeOnTerminate:= True;
TIdEnhancedIOHandler.RegisterIOHandler;
TCPClient:= TIdTCPClient.Create;
TCPClient.CreateIOHandler(TIdEnhancedIOHandler);
TCPClient.ConnectTimeout:= 1000;
TCPClient.ReadTimeout:= -1;
TCPClient.Host:= AHost;
TCPClient.Port:= APort;
RetSuccess:= False;
RetMessage:= 'Unknown error.';
end;
procedure TMainClient.Execute;
var CMD: Cardinal;
begin
TCPClient.Connect;
TCPClient.Socket.Write(CMD);
end;
From the Indy Help I understand that ...
帮助是旧的,并且包含过时的信息。
I must use CreateIOHandler
and specify my custom IOHandler class.
您可以这样做,但实际上并不需要这样做。在调用 TIdTCPClient.Connect()
之前,您可以简单地将自定义 class 的实例直接分配给 TIdTCPClient.IOHandler
属性,例如:
TCPClient := TIdTCPClient.Create;
TCPClient.IOHandler :- TIdEnhancedIOHandler.Create(TCPClient);
...
I do that and I get an exception which says that this class is not installed.
这意味着 Indy 的内部 GIOHandlerClassList
不包含任何派生自您指定给 CreateIOHandler()
.
的 class 类型的 class 类型
How cand I install it ? The variable GIOHandlerClassList
that holds the list is private...
您需要在运行时对自定义 class 类型调用 public RegisterIOHandler()
或 SetDefaultClass()
class 方法,例如在您的单元中initialization
部分,例如:
initialization
TIdEnhancedIOHandler.RegisterIOHandler();
然而,Indy 中唯一实际使用 CreateIOHandler()
的是 TIdSimpleServer
,因此在这种情况下无需“注册”您的自定义 class。
另一方面,如果没有分配 IOHandler
,TIdTCPClient.Connect()
会调用 TIdIOHandler.MakeDefaultIOHandler()
,并且使用由 TIdIOHandler.SetDefaultClass()
设置的 GIOHandlerClassDefault
(也称为 RegisterIOHandler()
)。因此,如果您希望 TIdTCPClient
为您创建自定义 class 类型的对象,您至少需要调用 SetDefaultClass()
,例如:
initialization
TIdEnhancedIOHandler.SetDefaultClass();
无论哪种方式,RegisterIOHandler()
/SetDefaultClass()
都应该只调用一次,例如在程序启动时。
UPDATE:您收到一个抽象错误,因为您是从 TIdIOHandlerSocket
派生 class,这是一个 abstract class,因为它没有实现在 TIdIOHandler
中声明为 abstract
的 ReadDataFromSource()
和 WriteDataToTarget()
方法。您需要从 TIdIOHandlerStack
派生您的 class,它派生自 TIdIOHandlerSocket
并实现这些方法。
我想为我的 Indy TCP 客户端使用自定义 TIdIOHandler
,但我不知道如何设置它。我创建了一个新的 IOHandler class,我注册了 TIdIOHandler.RegisterIOHandler
,然后我使用 TIdTCPClient.CreateIOHandler
和我的新处理程序引用。现在,当我尝试写入 TIdTCPClient.Socket
时,出现“抽象错误”异常......除了我的示例之外,我还需要配置其他东西吗?
TIdEnhancedIOHandler = class(TIdIOHandlerSocket)
public
function Acknowledge(Command: Cardinal = 0): Boolean;
end
{this is a client in a thread}
constructor TMyTCPClient.Create(const AHost: String; APort: Word);
begin
inherited Create;
FreeOnTerminate:= True;
TIdEnhancedIOHandler.RegisterIOHandler;
TCPClient:= TIdTCPClient.Create;
TCPClient.CreateIOHandler(TIdEnhancedIOHandler);
TCPClient.ConnectTimeout:= 1000;
TCPClient.ReadTimeout:= -1;
TCPClient.Host:= AHost;
TCPClient.Port:= APort;
RetSuccess:= False;
RetMessage:= 'Unknown error.';
end;
procedure TMainClient.Execute;
var CMD: Cardinal;
begin
TCPClient.Connect;
TCPClient.Socket.Write(CMD);
end;
From the Indy Help I understand that ...
帮助是旧的,并且包含过时的信息。
I must use
CreateIOHandler
and specify my custom IOHandler class.
您可以这样做,但实际上并不需要这样做。在调用 TIdTCPClient.Connect()
之前,您可以简单地将自定义 class 的实例直接分配给 TIdTCPClient.IOHandler
属性,例如:
TCPClient := TIdTCPClient.Create;
TCPClient.IOHandler :- TIdEnhancedIOHandler.Create(TCPClient);
...
I do that and I get an exception which says that this class is not installed.
这意味着 Indy 的内部 GIOHandlerClassList
不包含任何派生自您指定给 CreateIOHandler()
.
How cand I install it ? The variable
GIOHandlerClassList
that holds the list is private...
您需要在运行时对自定义 class 类型调用 public RegisterIOHandler()
或 SetDefaultClass()
class 方法,例如在您的单元中initialization
部分,例如:
initialization
TIdEnhancedIOHandler.RegisterIOHandler();
然而,Indy 中唯一实际使用 CreateIOHandler()
的是 TIdSimpleServer
,因此在这种情况下无需“注册”您的自定义 class。
另一方面,如果没有分配 IOHandler
,TIdTCPClient.Connect()
会调用 TIdIOHandler.MakeDefaultIOHandler()
,并且使用由 TIdIOHandler.SetDefaultClass()
设置的 GIOHandlerClassDefault
(也称为 RegisterIOHandler()
)。因此,如果您希望 TIdTCPClient
为您创建自定义 class 类型的对象,您至少需要调用 SetDefaultClass()
,例如:
initialization
TIdEnhancedIOHandler.SetDefaultClass();
无论哪种方式,RegisterIOHandler()
/SetDefaultClass()
都应该只调用一次,例如在程序启动时。
UPDATE:您收到一个抽象错误,因为您是从 TIdIOHandlerSocket
派生 class,这是一个 abstract class,因为它没有实现在 TIdIOHandler
中声明为 abstract
的 ReadDataFromSource()
和 WriteDataToTarget()
方法。您需要从 TIdIOHandlerStack
派生您的 class,它派生自 TIdIOHandlerSocket
并实现这些方法。