2012-11-13 171 views
1

我需要編寫一個Delphi 2009應用程序,它從套接字讀取數據。爲此,我需要爲TIdTCPServer.OnExecute事件編寫事件處理程序。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. 

回答

1

您需要爲您的類添加事件處理程序。然後將其連接起來:

TCPServer.OnExecute := Self.ExecuteHandler; 
4

正如大衛說(但並未完全顯示),你需要在你的線程類來聲明一個方法,然後將其分配給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. 

雖這麼說,你receiveing線程實際上是非常多餘的,因爲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. 
+0

尼斯。我發現你的技巧有點骯髒。但我明白你爲什麼不想實例化一個對象。一個很好的變體是使用類方法。當然你需要聲明一個類,但是你不需要實例化一個你想要避免的鍋爐主板的實例。 –

+0

很高興知道,謝謝。我更新了我的答案以使用它。 –