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

时间:2012-11-13 08:09:12

标签: delphi delphi-2009

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

我在GUI应用程序中找到了许多实现它的示例,但是我需要在控制台应用程序中执行它(没有任何窗口)。

如何修改下面的代码以添加事件处理程序(将其附加到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.

2 个答案:

答案 0 :(得分:4)

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

另外,您不应手动创建TIdSocketHandles集合。改为在现有的Add()集合上调用TIdTCPServer.Bindings

试试这个:

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已经是多线程的,所以你可以完全消除线程类:

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.

答案 1 :(得分:1)

您需要为您的类添加事件处理程序。然后连接起来:

TCPServer.OnExecute := Self.ExecuteHandler;