Delphi 控制台应用程序中的TIdTCPServer.OnExecute

Delphi 控制台应用程序中的TIdTCPServer.OnExecute,delphi,delphi-2009,Delphi,Delphi 2009,我需要编写一个Delphi2009应用程序,它从套接字读取数据。为此,我需要为TIdTCPServer.OnExecute事件编写一个事件处理程序 我在GUI应用程序中找到了很多实现这一点的例子,但我需要在没有任何窗口的控制台应用程序中实现这一点 我应该如何修改下面的代码,以便添加一个事件处理程序,将其附加到TCPServer,TCPServer会将收到的每条消息打印到调试输出中 unit ReceivingThreadUnit; interface uses Classes, Id

我需要编写一个Delphi2009应用程序,它从套接字读取数据。为此,我需要为TIdTCPServer.OnExecute事件编写一个事件处理程序

我在GUI应用程序中找到了很多实现这一点的例子,但我需要在没有任何窗口的控制台应用程序中实现这一点

我应该如何修改下面的代码,以便添加一个事件处理程序,将其附加到TCPServer,TCPServer会将收到的每条消息打印到调试输出中

unit ReceivingThreadUnit;

interface

uses
  Classes,
  IdTCPServer,
  IdSocketHandle,

  SysUtils,
  Windows;

type
  ReceivingThread = class(TThread)
    private
      TCPServer: TIdTCPServer;
    public
      procedure Run();

  end;

implementation

procedure ReceivingThread.Run();
var
  Bindings: TIdSocketHandles;
begin
  TCPServer := TIdTCPServer.Create(nil);

  //setup and start TCPServer
  Bindings := TIdSocketHandles.Create(TCPServer);
  try
    with Bindings.Add do
    begin
      IP := '127.0.0.1';
      Port := 9998;
    end;
    try
      TCPServer.Bindings:=Bindings;
      // Here I want to attach TCPServer to an OnExecute event handler
      TCPServer.Active:=True;
    except on E:Exception do
      OutputDebugString(PChar(E.ToString));
    end;
  finally
    Bindings.Free;
    TCPServer.Free;
  end;
  TCPServer.Active := true;
end;

end.

您需要向类中添加事件处理程序。然后将其连接起来:

TCPServer.OnExecute := Self.ExecuteHandler;

您需要向类中添加事件处理程序。然后将其连接起来:

TCPServer.OnExecute := Self.ExecuteHandler;

正如David所说,但没有完全说明,您需要在thread类中声明一个方法,然后将其分配给OnExecute事件

另一方面,您不应该手动创建TIdSocketHandles集合。改为在现有TIdTCPServer.Bindings集合上调用Add

试试这个:

unit ReceivingThreadUnit;

interface

uses
  Classes,
  IdTCPServer,
  IdSocketHandle,
  IdContext,

  SysUtils,
  Windows;

type
  ReceivingThread = class(TThread)
  private
    TCPServer: TIdTCPServer;
    procedure ExecuteHandler(AContext: TIdContext);
  public
    procedure Run;
  end;

implementation

procedure ReceivingThread.ExecuteHandler(AContext: TIdContext);
begin
  //...
end;

procedure ReceivingThread.Run;
begin
  //setup and start TCPServer
  TCPServer := TIdTCPServer.Create(nil);
  try
    with TCPServer.Bindings.Add do
    begin
      IP := '127.0.0.1';
      Port := 9998;
    end;
    TCPServer.OnExecute := ExecuteHandler;
    try
      TCPServer.Active := True;
    except
      on E: Exception do
        OutputDebugString(PChar(E.ToString));
    end;
    while not Terminated do
      Sleep(1000);
    TCPServer.Active := False;
  finally
    TCPServer.Free;
  end;
end;

end.
话虽如此,您的接收线程实际上是相当冗余的,因为TIdTCPServer已经是多线程的,所以您也可以完全删除thread类:

program MyApp;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Classes,
  IdTCPServer,
  IdSocketHandle,
  IdContext,

  SysUtils,
  Windows;

type
  TCPServerEvents = class
  public
    class procedure ExecuteHandler(AContext: TIdContext);
  end;

class procedure TCPServerEvents.ExecuteHandler(AContext: TIdContext);
begin
  //...
end;

var
  TCPServer: TIdTCPServer;
begin
  //setup and start TCPServer
  TCPServer := TIdTCPServer.Create(nil);
  try
    with TCPServer.Bindings.Add do
    begin
      IP := '127.0.0.1';
      Port := 9998;
    end;

    TCPServer.OnExecute := TCPServerEvents.ExecuteHandler;

    try
      TCPServer.Active := True;
    except
      on E: Exception do
        OutputDebugString(PChar(E.ToString));
    end;

    while (not stop condition) do
      Sleep(1000);

    TCPServer.Active := False;
  finally
    TCPServer.Free;
  end;
end.

正如David所说,但没有完全说明,您需要在thread类中声明一个方法,然后将其分配给OnExecute事件

另一方面,您不应该手动创建TIdSocketHandles集合。改为在现有TIdTCPServer.Bindings集合上调用Add

试试这个:

unit ReceivingThreadUnit;

interface

uses
  Classes,
  IdTCPServer,
  IdSocketHandle,
  IdContext,

  SysUtils,
  Windows;

type
  ReceivingThread = class(TThread)
  private
    TCPServer: TIdTCPServer;
    procedure ExecuteHandler(AContext: TIdContext);
  public
    procedure Run;
  end;

implementation

procedure ReceivingThread.ExecuteHandler(AContext: TIdContext);
begin
  //...
end;

procedure ReceivingThread.Run;
begin
  //setup and start TCPServer
  TCPServer := TIdTCPServer.Create(nil);
  try
    with TCPServer.Bindings.Add do
    begin
      IP := '127.0.0.1';
      Port := 9998;
    end;
    TCPServer.OnExecute := ExecuteHandler;
    try
      TCPServer.Active := True;
    except
      on E: Exception do
        OutputDebugString(PChar(E.ToString));
    end;
    while not Terminated do
      Sleep(1000);
    TCPServer.Active := False;
  finally
    TCPServer.Free;
  end;
end;

end.
话虽如此,您的接收线程实际上是相当冗余的,因为TIdTCPServer已经是多线程的,所以您也可以完全删除thread类:

program MyApp;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Classes,
  IdTCPServer,
  IdSocketHandle,
  IdContext,

  SysUtils,
  Windows;

type
  TCPServerEvents = class
  public
    class procedure ExecuteHandler(AContext: TIdContext);
  end;

class procedure TCPServerEvents.ExecuteHandler(AContext: TIdContext);
begin
  //...
end;

var
  TCPServer: TIdTCPServer;
begin
  //setup and start TCPServer
  TCPServer := TIdTCPServer.Create(nil);
  try
    with TCPServer.Bindings.Add do
    begin
      IP := '127.0.0.1';
      Port := 9998;
    end;

    TCPServer.OnExecute := TCPServerEvents.ExecuteHandler;

    try
      TCPServer.Active := True;
    except
      on E: Exception do
        OutputDebugString(PChar(E.ToString));
    end;

    while (not stop condition) do
      Sleep(1000);

    TCPServer.Active := False;
  finally
    TCPServer.Free;
  end;
end.
美好的我觉得你的把戏有点下流。但是我理解为什么你不想实例化一个对象。一个很好的变体是使用类方法。当然,您需要声明一个类,但不需要实例化一个实例,它是您想要避免的锅炉板的主要部分。我觉得你的把戏有点下流。但是我理解为什么你不想实例化一个对象。一个很好的变体是使用类方法。当然,您需要声明一个类,但不需要实例化一个实例,它是您想要避免的锅炉板的主要部分。